整数划分(三)
时间限制:1000 ms | 内存限制:65535 KB
- 描述
-
整数划分是一个经典的问题。请写一个程序,完成以下要求。
- 输入
- 每组输入是两个整数n和k。(1 <= n <= 50, 1 <= k <= n)
- 输出
- 对于输入的 n,k;
第一行: 将n划分成若干正整数之和的划分数。
第二行: 将n划分成k个正整数之和的划分数。
第三行: 将n划分成最大数不超过k的划分数。
第四行: 将n划分成若干个 奇正整数之和的划分数。
第五行: 将n划分成若干不同整数之和的划分数。
第六行: 打印一个空行 - 样例输入
-
5 2
- 样例输出
-
7 2 3 3 3
- 提示
- 样例输出提示:
1.将5划分成若干正整数之和的划分为: 5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+1
2.将5划分成2个正整数之和的划分为: 3+2, 4+1
3.将5划分成最大数不超过2的划分为: 1+1+1+1+1, 1+1+1+2, 1+2+2
4.将5划分成若干 奇正整数之和的划分为: 5, 1+1+3, 1+1+1+1+1
5.将5划分成若干不同整数之和的划分为: 5, 1+4, 2+3
#include <cstdio> #include <iostream> #include <cstring> #include <string> using namespace std; int dp[55][55]; int main () { int n, k, a, b, c, d, e; while(scanf("%d%d", &n, &k) != EOF) { // 把正整数i划分为不超过j的正整数的划分个数 for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { if(j>i) dp[i][j] = dp[i][i]; else if(j == i) dp[i][j] = dp[i][j-1] + 1; else dp[i][j] = dp[i][j-1] + dp[i-j][j]; } } a = dp[n][n]; c = dp[n][k]; // 把正整数划分为k个正整数的划分个数 for(int i=1; i<=n; i++) { for(int j=1; j<=k; j++) { if(j>i) dp[i][j] = 0; else if(j==i) dp[i][j] = 1; else dp[i][j] = dp[i-1][j-1] + dp[i-j][j]; } } b = dp[n][k]; // 把i划分为不超过j的奇数的划分个数 int odd = n&1 ? n : n-1; for(int i=1; i<=n; i++) { dp[i][1] = 1; for(int j=3; j<=odd; j+=2) { if(j>i) { if(i&1) dp[i][j] = dp[i][i]; else dp[i][j] = dp[i][i-1]; } else if(j==i) dp[i][j] = dp[i][i-2] + 1; else dp[i][j] = dp[i][j-2] + dp[i-j][j]; } } d = dp[n][odd]; // 把i划分为不同正整数的划分个数 for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { if(j>i) dp[i][j] = dp[i][i]; else if(j == i) dp[i][j] = dp[i][i-1] + 1; else dp[i][j] = dp[i][j-1] + dp[i-j][j-1]; } } e = dp[n][n]; printf("%d\n%d\n%d\n%d\n%d\n\n", a, b, c, d, e); memset(dp, 0, sizeof(dp)); } return 0; }
NYOJ 571 —— 各种划分数
时间: 2024-11-08 21:51:22