首页 > 代码库 > [CodeForces - 712D]Memory and Scores (DP 或者 生成函数)
[CodeForces - 712D]Memory and Scores (DP 或者 生成函数)
题目大意:
两个人玩取数游戏,第一个人分数一开始是a,第二个分数一开始是b,接下来t轮,每轮两人都选择一个[-k,k]范围内的整数,加到自己的分数里,求有多少种情况使得t轮结束后a的分数比b高。 (1 ≤ a, b ≤ 100, 1 ≤ k ≤ 1000, 1 ≤ t ≤ 100)
1.我一开始的想法是DP出玩i轮得分是j的方案数。然后状态数最多有t*(2*k*t)那么多,最坏情况下会有2e7那么多的状态,转移必须是O(1)的。
dp[i][j]=sum(dp[i-1][j-k....j+k])用个前缀和维护即可。 最后求答案的时候傻逼了,觉得必须枚举最后两人的得分,就放弃了这个做法。后来看了别人的题解,其实只要枚举第一个人的最后得分,那么第二个人可行的得分是连续的一段区间,也可以用前缀和来优化。 以上记为方法一。 时间复杂度O(k*t2)
2.方法二:一个重要的转化,原题等价于一个人一开始得分是a-b,然后玩2*t轮,最后得分要求大于0的方案数。 然后就和方法一一样了。
3.方法三:利用生成函数。观察可知 $(\frac{1+x+x^2+x^3+\cdots+x^{2k}}{x^k})^{2t}$次数大于0的项的系数和即为答案。 我们只要求出分子$(1+x+x^2+x^3+\cdots+x^{2k})^{2t}$的所有次数大于$2kt$的项的系数和即可。
我们可以把分子变形:
\begin{equation}
\begin{array}{rcl}
(1+x+x^2+x^3+\cdots+x^{2k})^{2t}&=&(1-x^{2k+1})^{2t}(\frac{1}{1-x})^{2t}\\
&=&\sum_{i=0}^{2t}C_{_{2t}}^{^i}(-1)^{i}x^{(2k+1)i} \sum_{j=0}^{\infty}C_{_{2t-1+j}}^{^{2t-1}}\ \ \ \ x^j
\end{array}
\end{equation}
(1+x+x2+?+x2k)2t=(1−x2k+11−x)2t=(1−x2k+1)2t×1(1−x)2t=(1−x2k+1)2t×(1+x+x2+x3+x4+?)2t
[CodeForces - 712D]Memory and Scores (DP 或者 生成函数)