腾讯笔试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))
#腾讯##笔试#
联想公司福利 1527人发布

