整数拆分
来源:互联网 发布:json乱码 编辑:程序博客网 时间:2024/04/29 19:44
参考 http://www.cppblog.com/bennycen/archive/2011/03/28/142877.html
把一个整数拆分成大于0的整数之和,并且拆分方案不重复。
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
共10种方案
方法1:
对于这种求不重复组合的问题,就是进行有序组合就行了,就是按照升序
int combine(int rem, int curr) { if (rem == 0) return 1; int sum = 0; for (;curr <= rem; ++curr) sum += combine(rem - curr, curr); return sum;}cout<<combine(6,1) - 1<<endl;
方法2:
动态规划
首先假设正整数n拆分成k个数(不允许有0),用f(n,k)表示正整数n拆分成k个数的可行拆分种类的数目。
那么
f(n,n)表示n拆分成n个数(即只有n个1),显然f(n,n) = 1
然后,可以按照这k份中是否有一份的数为1分成两类:
1) 这k份中没有1份含1的:那么可以在n中拿出k个"1"出来,分到k份中,再将剩下n-k分到k份中,于是这时有
f(n,k) = f(n-k,k)
2) 这k份中至少有一份含有1:首先在n中拿1个"1"出来,再将剩下n-1分到k-1份中,于是这时有:f(n,k) = f(n-1,k-1)
综合起来就是:
f(n,n) = 1
f(n,k) = f(n-k,k) + f(n-1,k-1)
int combine1( int n,int k) { vector<vector<int> > v(n+1); for (int i = 0; i <=n ;++i) v[i].resize(k+1,0); v[0][0] = 1; for (int i = 1; i <= n; ++i) { for (int j = 1; j <=k ; ++j) { if (i - j >=0) v[i][j] += v[i-j][j]; if (i - 1 >=0 && j - 1 >=0) v[i][j] += v[i-1][j-1]; } } int sum = 0; for (int i = 2; i <=k ; ++i) sum += v[n][i]; return sum;}cout<<combine1(6,6)<<endl;
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 拆分整数
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 整数按和拆分
- 整数合并和拆分
- 整数的拆分
- 整数拆分问题
- 类图中关系
- VC 6.0 GPIB编程,模块与综测仪通讯,实现自动测试
- dbcp配置详解
- mysql如何使用load data infile导入中文数据
- 如何使用AV Foundation从摄像头将视频帧捕获为图像
- 整数拆分
- 自定义函数 直角等腰三角 解法2
- MongoDB实战系列之四:mongodb副本集部署
- 散户为什么不戒股
- Google Web工具包 GWT
- android移植之request_suspend_state: wakeup & init: untracked pid xx exited问题的解决
- 调用函数输出1000以内的回文素数。(第十二周上机任务).
- 分段函数,求。。
- 第十二周项目三四数的最大公约数