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\)

posted @ 2022-08-05 01:28  OIer某罗  阅读(35)  评论(0编辑  收藏  举报