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])$

实现

没有代码!

上面算法知道了,那么还剩下

  1. 递推,for一下
  2. MOD运算别忘了
  3. 组合数(才2k随便搞),乘法逆元 O(n) 或者 组合数递推关系(高中知识) O(n^2),不过看递推基本都要算到,直接无脑递推就好了

参考

https://codeforces.com/blog/entry/69244