整数的拆分问题
来源:互联网 发布:手机淘宝账号在哪里 编辑:程序博客网 时间:2024/05/17 21:51
// 整数的拆分.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>#include <vector>using namespace std;int q(int n , int m){if(n < 1 || m < 1)return 0;if(n == 1 || m == 1)return 1;if(n < m)return q(n , n);if(n == m)return q(n , m - 1) + 1;return q(n , m - 1) + q(n - m , m);}void dfs(int sum , vector<int>& vec , int curnum , int id){int i;if(curnum == sum){static int inum = 1 ;cout<<"方案 "<<inum++<<": ";for(i = 0; i < vec.size() ; ++i)cout<<vec[i]<<" ";cout<<endl;return;}for(i = id ; i <= sum; ++i){if(curnum + i <= sum){vec.push_back(i);dfs(sum , vec , curnum + i , i);vec.pop_back();}elsebreak;}}int main(void){int n,i,j,dp[121][121];for(i = 1 ; i < 121 ; ++i){for(j = 1 ; j < 121 ; ++j){if(i == 1 || j == 1)dp[i][j] = 1;else if(i > j)dp[i][j] = dp[i][j-1] + dp[i-j][j];else if(i == j)dp[i][j] = dp[i][j-1] + 1;elsedp[i][j] = dp[i][i];}}while(scanf("%d",&n)!=EOF){cout<<dp[n][n]<<endl;cout<<q(n,n)<<endl;vector<int> vec;dfs(n , vec , 0 , 1);cout<<endl;}system("pause");return 0;}如,对于正整数n=6,可以拆分为:
6
5+1
4+2, 4+1+1
3+3, 3+2+1, 3+1+1+1
2+2+2, 2+2+1+1, 2+1+1+1+1
1+1+1+1+1+1+1
现在的问题是,对于给定的正整数n,程序输出该整数的拆分种类数(HDOJ 1028)。
DP思路:
n = n1 + n2 + n3 + n4 + .... + nk
状态表示:将n划分为k个数相加的组合方案数记为 q(n,k)。(相当于将n个苹果放入k个盘子)
状态转移:
(1)若k>n,则盘子数大于苹果数,至少有k-n个空盘子,可以将其拿掉,对组合方案数无影响。
q(n,k) = q(n,n)
(2)若k<=n,则盘子数小于等于苹果数,则分为两种情况
1.至少有一个盘子空着:q(n,k) = q(n,k-1)
2.所有盘子都不空:q(n,k) = q(n-k,k)
q(n,k) = q(n,k-1) + q(n-k,k)
没想明白为什么分为盘子 都不空 和 有一个空 两种情况???
- 整数的拆分问题
- 整数的拆分问题
- 整数的拆分问题(允许重复)
- 整数的拆分问题(不允许重复)
- 整数拆分问题的分析(dfs)
- 整数拆分问题的四种解法
- 整数拆分问题
- 整数拆分问题
- 整数拆分问题
- 整数拆分问题
- 整数拆分问题详解
- 整数拆分问题
- 整数拆分问题
- 整数的拆分
- ecnu1009 - 整数的拆分
- 整数的加法拆分
- 整数的拆分1
- 整数的拆分2
- Linux 内核进程管理之进程ID
- vs2010编译glut-3.7
- Java高级特性之new一个内部类
- 1053. Path of Equal Weight——深搜
- 警惕租房的十大禁忌_家居风水自查
- 整数的拆分问题
- 给定两个正整数A和B,把A变成B需要几位?也就是说A和B之间的位数有多少个是不同的?
- servlet学习笔记(二)
- 我是不是你真疼爱的人 你为什么不说话
- Apache CXF Spring SOAP example
- hdu Disney's FastPass(状态压缩dp)
- JavaSwing图形界面编程之消息提示框(三)
- POJ-3261-Milk Patterns
- sql语句如何获得当前日期