标签:ret online editable limit style 上传 lin profile pac
http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=571
整数划分是一个经典的问题。请写一个程序,完成以下要求。
5 2
7
2
3
3
3
#include <iostream> #include <cstring> using namespace std; int dp[150][150]; int n, k; int main(){ while(cin >> n >> k){ //将n划分成若干正整数之和的划分数 for(int i = 0; i <= n; i++){ for(int j = 0; j <= n; j++){ if(i < j){ dp[i][j] = dp[i][i]; continue; } if(i == 1 || i == 0 || j == 1) dp[i][j] = 1; else dp[i][j] = dp[i - j][j] + dp[i][j - 1]; } } int f3 = dp[n][k]; cout << dp[n][n] << endl; memset(dp, 0, sizeof(dp)); // 将n划分成k个正整数之和的划分数。 for(int i = 1; i <= n; i++){ for(int j = 1; j <= n; j++){ if(i < j){ dp[i][j] = 0; continue; } if(j == 1){ dp[i][j] = 1; } else dp[i][j] = dp[i - 1][j - 1] + dp[i - j][j]; } } cout << dp[n][k] << endl; memset(dp, 0, sizeof(dp)); //将n划分成最大数不超过k的划分数。与第一个相同: cout << f3 << endl; memset(dp, 0, sizeof(dp)); //将n划分成若干个 奇正整数之和的划分数。 int ou[150][150]; ou[0][0] = dp[0][0] = 1; for(int i = 1; i <= n; i++){ for(int j = 1; j <= n; j++){ //i,j必须从1开始!!! if(i < j){ dp[i][j] = 0; continue; } ou[i][j] = dp[i - j][j]; dp[i][j] = dp[i - 1][j - 1] + ou[i - j][j]; } } int sum = 0; for(int i = 1; i <= n; i++){ sum += dp[n][i]; } cout << sum << endl; memset(dp, 0, sizeof(dp)); //将n划分成若干不同整数之和的划分数。 for(int i = 0; i <= n; i++){ for(int j = 0; j <= n; j++){ if(i < j){ dp[i][j] = dp[i][i]; continue; } if(i == 1 && j >= 1) dp[i][j] = 1; else if(i == 0) dp[i][j] = 1; else dp[i][j] = dp[i - j][j - 1] + dp[i][j - 1]; } } cout << dp[n][n] << endl; } return 0; }
不能ac的递归代码:
#include <iostream> #include <cstring> using namespace std; int dp[105][105]; int n, k; //将n划分成若干正整数之和的划分数 int fun1(int i, int j){ if(i < 0 || j < 0) return 0; if(dp[i][j]) return dp[i][j]; if(i == 0 || i == 1 || j == 1) return dp[i][j] = 1; return dp[i][j] = fun1(i - j, j) + fun1(i, j - 1); } // 将n划分成k个正整数之和的划分数。 int fun2(int i, int j){ if(i < 0 || j < 0) return 0; if(i < j) return dp[i][j] = 0; if(dp[i][j]) return dp[i][j]; if(j == 1){ //注意与上面的区别 return dp[i][j] = 1; } return dp[i][j] = fun2(i - 1, j - 1) + fun2(i - j, j); } //将n划分成若干个 奇正整数之和的划分数。 int fun3(int i, int j){ // if(i < 0 || j < 0) // return 0; // if(dp[i][j]) // return dp[i][j]; // if(i & 1 && j == 1){ // return dp[i][j] = 1; // } // return dp[i][j] = fun3(i - 1, j - 1) + fun3(i - 2 * j, j - 1); int ou[150][150]; ou[0][0] = dp[0][0] = 1; for(int i = 1; i <= n; i++){ for(int j = 1; j <= n; j++){ //i,j必须从1开始!!! if(i < j){ dp[i][j] = 0; continue; } ou[i][j] = dp[i - j][j]; dp[i][j] = dp[i - 1][j - 1] + ou[i - j][j]; } } } int fun4(int i, int j){ if(i < 0 || j < 0) return 0; if(dp[i][j]) return dp[i][j]; if(i < j) return dp[i][j] = fun4(i, i); if(i == 1 && j >= 1) return dp[i][j] = 1; if(i == 0) return dp[i][j] = 1; return dp[i][j] = fun4(i - j, j - 1) + fun4(i, j - 1); } int main(){ while(cin >> n >> k){ cout << fun1(n, n) << endl; memset(dp, 0, sizeof(dp)); cout << fun2(n, k) << endl; memset(dp, 0, sizeof(dp)); cout << fun1(n, k) << endl; memset(dp, 0, sizeof(dp)); int sum = 0; fun3(n,n); for(int i = 1; i <= n; i++){ sum += dp[n][i]; } cout << sum << endl; memset(dp, 0, sizeof(dp)); cout << fun4(n, n) << endl; } return 0; } //https://blog.csdn.net/lin_disguiser/article/details/50574818
标签:ret online editable limit style 上传 lin profile pac
原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/9206145.html