《1402 - 整数划分问题》

 母函数注意对几个分类即可。

看起来比较麻烦就是限定次数K,但是我们对dp再加一维次数之后,其实这个问题也就得到了解决。

PS:没有多组读入判我WA,还以为代码哪里不对。。

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> pii;
const int N = 5e4 + 5;
const int M = 1e5 + 5;
const LL Mod = 998244353;
#define pi acos(-1)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

int n,mx;
LL dp[2][55],ans1,ans2,ans3,ans4,ans5,f[2][55][55];
void solve() {
    memset(dp,0,sizeof(dp));
    for(int i = 1;i <= n;++i) {
        memset(dp[i % 2],0,sizeof(dp[i % 2]));
        for(int j = 0;j <= n;++j) {
            for(int k = 0;k <= n;k += i) {
                if(k + j <= n) {
                    if(i == 1) dp[i % 2][k + j] = 1;
                    else dp[i % 2][k + j] += dp[(i + 1) % 2][j];
                }
            }
        }
    }
    ans1 = dp[n % 2][n];
    memset(f,0,sizeof(f));
    for(int i = 0;i <= n;++i) {
        f[1 % 2][i][i] = 1;
    }
    for(int i = 2;i <= n;++i) {
        memset(f[i % 2],0,sizeof(f[i % 2]));
        for(int j = 0;j <= n;++j) {
            int cnt = 0;
            for(int k = 0;k <= n;k += i,++cnt) {
                for(int m = 0;m <= mx;++m) {
                    if(k + j <= n && m - cnt >= 0) f[i % 2][m][k + j] += f[(i + 1) % 2][m - cnt][j];
                }
            }
        }
    }
    ans2 = f[n % 2][mx][n];
    memset(dp,0,sizeof(dp));
    for(int i = 1;i <= mx;++i) {
        memset(dp[i % 2],0,sizeof(dp[i % 2]));
        for(int j = 0;j <= n;++j) {
            for(int k = 0;k <= n;k += i) {
                if(k + j <= n) {
                    if(i == 1) dp[i % 2][k + j] = 1;
                    else dp[i % 2][k + j] += dp[(i + 1) % 2][j];
                }
            }
        }
    }
    ans3 = dp[mx % 2][n];
    memset(dp,0,sizeof(dp));
    for(int i = 1;i <= n;++i) {
        if(i % 2 == 0) {
            for(int j = 0;j <= n;++j) dp[i % 2][j] = dp[(i + 1) % 2][j];
            continue;
        }
        memset(dp[i % 2],0,sizeof(dp[i % 2]));
        for(int j = 0;j <= n;++j) {
            for(int k = 0;k <= n;k += i) {
                if(k + j <= n) {
                    if(i == 1) dp[i % 2][k + j] = 1; 
                    else dp[i % 2][k + j] += dp[(i + 1) % 2][j];
                }
            }
        }
    }
    ans4 = dp[n % 2][n];
    memset(dp,0,sizeof(dp));
    dp[1 % 2][0] = dp[1 % 2][1] = 1;
    for(int i = 2;i <= n;++i) {
        memset(dp[i % 2],0,sizeof(dp[i % 2]));
        for(int j = 0;j <= n;++j) {
            for(int k = 0;k <= i;k += i) {
                if(k + j <= n) dp[i % 2][k + j] += dp[(i + 1) % 2][j];
            }
        }
    }
    ans5 = dp[n % 2][n];
}
int main() {
    while(cin >> n >> mx) {
        solve();
        printf("%lld\n%lld\n%lld\n%lld\n%lld\n\n",ans1,ans2,ans3,ans4,ans5);
    }
    system("pause");
    return 0;
}
View Code

 

posted @ 2021-05-27 19:25  levill  阅读(54)  评论(0编辑  收藏  举报