腾讯笔试9.15-建城池方案数

原题概述

有n座城池,编号为1-n,每个城池可选择 建/不建 防御关卡,同时给了m个约束,每个约束用区间[l, r]表示,代表编号l-r区间至少有1个防御关卡,问总共有多少种建造方案?

输入:第一行n,m,接下来m行代表每个约束中的l, r,输出方案数对1e9+7取余结果

思路

代码

from functools import lru_cache
MOD = 10 ** 9 + 7
modpow2 = lambda exp: pow(2, exp, MOD)
n, m = map(int, input().split())
pos = sorted([tuple(map(int, input().split())) for _ in range(m)])

@lru_cache(maxsize=None)
def solve(k, lastl, lastr):
    if k < len(pos):
        l, r = pos[k][0] - 1, pos[k][1]
        if l >= lastr:
            # [lastl, lastr) 至少1个, [lastr, l) 任取, 递归考虑[l, r)和剩下区间
            ans = (modpow2(l - lastl) - modpow2(l - lastr)) * solve(k + 1, l, r)
        elif r <= lastr:
            # [lastl, l) 任取, 递归考虑[l, r)和剩下区间
            ans = modpow2(l - lastl) * solve(k + 1, l, r)
        else:
            # 情况1: [lastl, l) 至少1个, 递归考虑[l, r) 和剩下区间
            # 情况2: [lastl, l) 都没有, 递归考虑[l, lastr) 和剩下区间
            ans = (modpow2(l - lastl) - 1) * solve(k + 1, l, r) + solve(k + 1, l, lastr)
    else:
        # 边界情况,[lastl, lastr) 至少1个, [lastr, n) 任取
        ans = modpow2(n - lastl) - modpow2(n - lastr)
    return ans % MOD

print(solve(0, -1, 0))

#腾讯##笔试#
全部评论

相关推荐

点赞 评论 收藏
分享
评论
3
7
分享
牛客网
牛客企业服务