CF1784D Wooden Spoon (组合DP+FFT)

link

link

div2F(div1D)

题意:有 \(2^n\) 个人,编号为1到 \(2^n\) 的整数,他们进行淘汰赛,比赛形式是一个满二叉树,每局比赛编号小的赢。木勺奖颁发给满足“第一次比赛输了;在上述比赛赢了他们的人第二次比赛输了;在上述比赛赢的他们的人第三次比赛输了;...;在上述比赛赢了他们的人在最后一次比赛输了”的选手,可以证明满足这样条件的选手只有1个。考虑所有 \((2^n)!\) 个排列构成的情况,每种情况一定会仅有一个人获得木勺奖,求每个人获得木勺奖的情况数量。输入只包含:\(1\le n\le 20\)

分析:首先设 \(2^i\) 个人比赛时编号第 \(j\) 小的人获得木勺的情况数为 \(dp[i][j]\) ,也就是输出的答案,为了方便我们这里从 0 开始编号,也就是 \(0\le j\le2^i-1\)

不难得到转移方程为

\(dp[i][j]=2(2^{i-1})!\sum_{k=0}^{2^{i-1}-1}dp[i-1][k] \binom{j-1}{k}\binom{2^i-j-1}{2^{i-1}-k-1}\)

说明:考虑这个人在它所在的那一半子树,要是他获得木勺,必须满足这个子树里面对应位置获得木勺,并且这里面最小值比另一个子树的小,那么另一个子树的最小值必定是全局最小值(题目里是1,我从0开始标号那么就是0)

考虑枚举这个j在自己子树里对应的k,\(dp[i-1][k]\)就是自己子树对应的情况,别人子树可以随便放,也就是\((2^{i-1})!\),两个子树可以xjb换位置也就是再乘以一个2
,然后就是分配问题了,j必须在自己子树里排位是k,并且自己子树不能是最小值,因此抛去0,\([1,j-1]\)里选出k个作为\([0,k-1]\)(注意是从0标号),后面就是\([j+1,2^i-1]\)里选出\(2^{i-1}-k-1\)个作为\([k+1,2^{i-1}-1]\)区间的值

初始条件可以参考样例的 \(dp[1][0]=0,dp[1][1]=2\)

然后考虑优化,可以把组合数拆了

\(dp[i][j]=2(2^{i-1})!(j-1)!(2^i-j-1)!\sum_{k=0}^{2^{i-1}-1}\frac{dp[i-1][k]}{k!(2^{i-1}-k-1)!}\cdot\frac{1}{(j-k-1)!(2^{i-1}-(j-k))!}\)

发现里面是个卷积,设 \(f[t]=\frac{dp[i-1][t]}{t!(2^{i-1}-t-1)!},g[t]=\frac{1}{(t-1)!(2^{i-1}-t)!}\) ,然后可以用fft优化

由于本题刚好每次DP是\(2^n\),所以就不用补齐,注意 f 函数只有一半,但是 g 要全算出来,对于阶乘溢出可以额外写一个函数判,如果传入负数直接返回0

复杂度为 \(\sum_{i=1}^{\log_n}i 2^i=O(n\log n)\) ,不过常数有点大

代码太丑就不放了

这种DP里面只有cnm的一般都可以拆了然后写成卷积,洛谷上有一车类似的

CF连掉了四次分靠一个FFT拉了回来,写个题解纪念一下

posted @ 2023-02-06 15:55  ghj1222  阅读(157)  评论(0编辑  收藏  举报