《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; }