腾讯笔试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))

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

相关推荐

不愿透露姓名的神秘牛友
07-07 13:35
虽然不怎么光彩,经过这件事,可能我真的要去认同“面试八股文早该淘汰!不会用AI作弊的程序员=新时代文盲!”这句话了
HellowordX:Ai的出现是解放劳动力的,不是用来破坏公平竞争环境的,这样下去,轻则取消所有线上面试,严重了会影响整个行业对所有人产生影响,企业会拉高入职考核各种离谱考核会层出不穷
你找工作的时候用AI吗?
点赞 评论 收藏
分享
05-21 15:47
门头沟学院 Java
浪漫主义的虹夏:项目有亮点吗,第一个不是纯玩具项目吗,项目亮点里类似ThreadLocal,Redis储存说难听点是花几十分钟绝大部分人都能学会,第二个轮子项目也没体现出设计和技术,想实习先沉淀,好高骛远的自嗨只会害了自己
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
3
7
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务