码迷,mamicode.com
首页 > 其他好文 > 详细

40-整数划分(三)

时间:2018-06-20 22:36:16      阅读:271      评论:0      收藏:0      [点我收藏+]

标签:ret   online   editable   limit   style   上传   lin   profile   pac   

http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=571

整数划分(三)

时间限制:1000 ms  |  内存限制:65535 KB
难度:5
 
描述

整数划分是一个经典的问题。请写一个程序,完成以下要求。

 

 

 
输入
多组输入数据。
每组输入是两个整数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
上传者
ACM_李如兵
https://blog.csdn.net/lin_disguiser/article/details/50574818
https://blog.csdn.net/ruzhuxiaogu/article/details/26749063
只想说下多组输入!!!
#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         

  

 

40-整数划分(三)

标签:ret   online   editable   limit   style   上传   lin   profile   pac   

原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/9206145.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!