ARC162E
题面
给定长度为 \(n\) 的序列 \(A\),求长度为 \(n\) 的序列 \(B\) 的个数,模 \(998244353\),要求 \(B\) 满足以下条件:
- 值域 \([1, n]\)。
- \(i\) 的个数不超过 \(A_i\)。
- \(B_i\) 的个数不超过 \(A_i\)。
数据范围:\(n\le 500\) 。
题解
当时想的是先把 \(a_i\) 排序,然后对于数 \(i\) 来考虑,其最多出现次数要么是 \(a_i\) ,要么就是第一个 \(i\) 的位置。
但是这样就要记 \(f_{i,j,k}\) ,表示当前考虑到 \(i\) ,还没放的数的个数 \(j\),\(i+1\sim n\) 中还没放数的个数是 \(k\) 。转移是 \(O(n)\) 的,然后就 G 了。
但是我们可以这样:对于每个 \(i\) ,考虑出现 \(i\) 次的数有多少个,这样记 \(f_{i,j,k}\) ,为考虑到 \(i\) ,已经放入的数是 \(j\) ,占用的空位是 \(k\) 。虽然状态数是一样的,但这样的转移是只有 \(O(\log)\) 次的!
所以就有:
\[f(i,j,k)\leftarrow f(i-1,j-t,k-ti)\times\binom{suc_i-k+ti}{i,i,...,i}\times\binom{suc_i-j+t}t
\]
启发
- 对于这种dp,如果发现转移 \(O(n)\) 无法通过时,可以想想对于每个出现次数去考虑。