题解:CF2066D2 Club of Young Aircraft Builders (hard version)

· · 题解

题解

对于计数题考虑找充要条件。考虑一个数字能填需要满足其前面还没有 c 个数大于它,注意这个限制是后缀的,所以我们考虑值域的前缀。对于 1 我们只能放在 [1,c],以此类推,我们能够得到 i 能够放置的区间 [1,c+\sum\limits_{j<i}\text{cnt}_j],其中 \text{cnt}_jj 的数量。于是我们可以对其考虑 dp,设 f_{i,j} 表示考虑到 i 填了 j 个数的方案数。转移考虑枚举 i 放了多少个,设为 k,其上界是 \min(j,c)。此时我们能够知道 i 填数范围是 [1,c+j-k],首先我们需要判断这个上界是否合法,因为可能存在已经给出的 i 的最右边不在区间内的情况。判断转移合法性之后就简单了,现在只需考虑填数的方案数即可。因为之前已经有 j-k 个数,于是还剩下 c 个空位,但是考虑到原来的序列本身还有一些数已经确定,于是还要减去这段前缀区间内 \ge i 的数的个数,设为 s。考虑我们需要将 ki 放进去,但是可能原来序列中也有一些 i 了,其数量设为 t,那么我们的方案数就是 c-s\choose k-t。于是最后的 dp 式子就是:

f_{i,j}=\sum_{k\le\min(c,j)}f_{i-1,j-k}\times{c-s\choose k-t}

时间复杂度 \mathcal O(nmc)