zoukankan      html  css  js  c++  java
  • 40-整数划分(三)

    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         
    

      

  • 相关阅读:
    【原】 POJ 1308 Is It A Tree? 并查集树结构 解题报告
    终于决定投身Linux怀抱
    Inside the C++ Object Model
    Fedora 下 OpenCV 的安装
    sed 与 awk
    工具链接收藏
    [转] 计算机视觉领域稍微容易中的期刊
    QtCreator开发多文档编辑器(Project 1)
    Fedora 17: Grub Rescue
    做文档类的工作总是让我感到一些烦躁
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/9206145.html
Copyright © 2011-2022 走看看