Educational Codeforces Round 133 D 解题报告
题意:给定 \(n,k\),可以从 \(0\) 开始,第一次加 \(k\) 的若干倍,第二次加 \(k+1\) 的若干倍...一直加到 \(n\)。对于 \(n=1,2,...,n\) 求方案数。
\(1 \le k \le n \le 2 \times 10^5\)
分析:是一道背包问题。对于 \(k,k+1,k+2,...,k+632\)(当 \(n=2 \times 10^5,k=1\) 时有上界 \(632\))取前一段物品,每一种物品可以取 \(1,...,\inf\) 个。是完全背包,但是需要加一个“强制跳转”的操作。
设 \(dp[i][j]\) 为只使用前 \(i\) 件物品(每一件都必须至少用一个)到达 \(j\) 的方案数。那么有如下转移:(先是像 01 背包那样强制(即覆盖之前的)往前跳一次,然后是完全背包)
dp[0]=1;
f(j,k,k+632){
for(int i = n; i >= 0; i--) {
if(i >= j) dp[i] = dp[i - j];
else dp[i] = 0;
}
f(i,1,n){
if(i-j<0)continue;
dp[i]=dp[i]+dp[i-j]; dp[i] %= mod;
ans[i] += dp[i]; ans[i] %= mod;
}
}
时间复杂度 \(O(n \sqrt n)\)(\(632 \sim \sqrt n\))