返回顶部

Codeforces Round #240 (Div. 1) B. Mashmokh and ACM (DP)

  • 题意:给出两个正整数\(n\)\(k\),构造一个长度为\(k\)的好序列\(b_1,b_2,...,b_k(1\le b_1\le b_2\le ...\le b_k \le n)\),并且满足\(b_i|b_{i+1}\),问最多能够造出多少这样的序列(同一个元素可以出多次).

  • 题解:我们记\(dp[i][j]\)表示长度为\(i\),序列末尾是\(j\)的好序列个数,首先,每个数自己可以构成一个好序列,我们先将\(dp[1][i]=1 \ (1\le i\le n)\),然后枚举序列长度\([2,k]\),\(j\)表示因子,\(j*k\)表示我们序列末尾的数,每个数的状态都可以由序列长度为\(i-1\)的它的因子\(j\)转移而来,所以我们可以写出状态转移方程\(dp[i][j*k]=dp[i][j*k]+dp[i-1][j]\).

  • 代码:

    int n,k;
    int dp[2010][2010];
    int ans;
    
    int main() {
        //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        n=read(),k=read();
        for(int i=1;i<=n;++i) dp[1][i]=1;
    
        for(int i=2;i<=k;++i){
            for(int j=1;j<=n;++j){
                for(int k=1;k*j<=n;++k){
                    dp[i][k*j]=(dp[i][k*j]+dp[i-1][j])%mod;
                }
            }
        }
    
        for(int i=1;i<=n;++i){
            ans=(ans+dp[k][i])%mod;
        }
    
        printf("%d\n",ans);
    
        return 0;
    }
    
posted @ 2020-10-22 19:49  _Kolibri  阅读(79)  评论(0)    收藏  举报