orz qyc
小 A,小 B,小 C 在玩游戏。他们每个人分别有 n,m,k 张牌,每张牌上面写着 a,b,c 三个字母中的其中一个,每个回合有一个人出牌,如果出牌为 a 则小 A 下一个回合出牌,如果出牌为 b 则小 B 下一个回合出牌,小 C 同理。若轮到某位玩家出牌时,其手中无牌,则该位玩家获胜。
现在小 A 第一个出牌,对所有 3n+m+k 种手牌拥有的可能性计算小 A 获胜的方案数,对 109+7 取模。
如果按照打出的顺序排成一个长度为 l 的序列,小 A 获胜当且仅当:a 恰好出现了 n 次且在最后一次出现,b 出现了不多于 m 次,c 出现了不多于 k 次。
而这个长度为 l 的序列对应了 3n+m+k−l 种手牌拥有的情况。
n 次是一定打的,枚举 b,c 出现的次数 t,然后枚举 b 出现的次数 i:
m+k∑t=0(n+t−1n−1)3m+k−tm∑i=t−k(ti)
第一个组合数是除了最后一个是 a,确定 (n−1) 个 a 的位置,3m+k−t 是计算的对应了多少种手牌拥有情况,最后一个组合数为在 t 个 b,c 都可以填的空位挑出 i 个填 b,注意这个组合数可能会出现 i<0 或 i>t 的情况,由于是考虑其实际的组合意义,所以当出现这样的情况时视为 0.
最后一个实际上是组合数一行的区间和,众所周知这个的计算是困难的,由于这个区间和的形式比较特殊,考虑递推出这个东西:
S(t)=m∑i=t−k(ti)=m∑i=t−k(t−1i−1)+m∑i=t−k(t−1i)=m−1∑i=t−k−1(t−1i)+m∑i=t−k(t−1i)= 2⋅m∑i=t−k−1(t−1i)−(t−1m)−(t−1t−k−1)= 2⋅S(t−1)−(t−1m)−(t−1t−k−1)
至此,可以在 O(n+logmod) 的时间复杂度内解决问题。
Code
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?