Codeforces Round 581
又是一个 大家都会的组合数学,就我不会
本题目2400评分
大意
列出n个1 m个-1的所有排列
求(每个排列的最大前缀和(>=0))的和
数据范围
0<=n,m<=2000
题解
注翻译自官方题解
k[x][y]
表示由 x个1 和y个-1组成的 最大前缀和为0的 数组个数
k[0][y] = 1
显然 只有一种情况
k[x][y] = 0 (if x>y)
k[x][y] = k[x-1][y] + k[x][y-1]
关于上面的转移
从是最后增加一个数字转移进行考虑,分别讨论最后一位是1或-1,
1的情况,由x<=y得 最大前缀和不会超过0
-1的情况,明显了增加负1不会影响前缀和
然后
dp[x][y]
为方案数 则 dp[n][m]
为答案
dp[0][y] = 0
显然
dp[x][0] = x
显然
否则
$d[x][y] = (\binom{x+y-1}{y}+d[x-1][y]) + (d[x][y-1] - (\binom{x+y-1}{x}-k[x][y-1]))$
解释:分类首位是1或-1讨论
首位是1 剩余部分 的方案数是如下组合数,对于每个方案的最大前缀和都+1了,除了首位的部分是d[x-1][y]
$\binom{x+y-1}{y} + d[x-1][y]$
首位是-1, 剩余部分 的方案数是如下组合数,但并不是对于每个方案的最大前缀和都-1了,只有那些最大前缀和>0
的才会影响,所以是 -1* (组合数 - (最大前缀和为0的个数))
,除了首位的部分是d[x][y-1]
$d[x][y-1] - ( \binom{x+y-1}{x}-k[x][y-1])$
实现
没有代码!
上面算法知道了,那么还剩下
- 递推,for一下
- MOD运算别忘了
- 组合数(才2k随便搞),乘法逆元
O(n)
或者 组合数递推关系(高中知识)O(n^2)
,不过看递推基本都要算到,直接无脑递推就好了