整数划分问题(算法分析与设计 P12):将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥1,k≥1。正整数n的这种表示称为正整数n的划分。求正整数n的不同划分个数和方案。例如正整数6有如下11种不同的划分:
- 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
由于将思路写作注释更方便理解,就不再在前面赘述了,给出代码及思路如下:
- #include
- int list[255];
- // num: 要分割的原始数字, n: 当前要分割的数字, k: 已经分割出的数量, sum: 已分割出的数字之和
- void split(int num, int n = 0, int k = 0, int sum = 0){
- // 如果当前要分割的数字未传入,则当前分割的数字即为要分割的原始数字,减少传入参数数量
- if(n == 0){
- n = num;
- }
- // 如果已分割的数字之和等于要分割的原始数字,即分割完毕
- if(sum + n == num){
- // 将最后一个数字存入数组
- list[k] = n;
- // 判断已分割的数字是否后面小于前面,防止重复
- bool flag = true;
- // 暂时未想到更好办法去除重复项,每次都要遍历数组,性能较低
- for(int i = 1; i <= k; ++i){
- if(list[i] > list[i - 1]){
- flag = false;
- }
- }
- // 如果数组合法,则输出
- if(flag){
- printf("%d", list[0]);
- for(int i = 1; i <= k; ++i){
- printf("+%d", list[i]);
- }
- printf("\n");
- }
- }
- // 从小到大进行分割
- for(int i = 1; i < n; ++i){
- // 分割剩下的数字存入数组
- list[k] = n - i;
- // 分割出的数字继续分割
- split(num, i, k + 1, sum + n - i);
- }
- }
- int main(){
- int n;
- while(~scanf("%d", &n)){
- split(n);
- }
- return 0;
- }
=======================签 名 档=======================
原文地址(我的博客):http://www.clanfei.com/2012/12/1672.html
欢迎访问交流,至于我为什么要多弄一个博客,因为我热爱前端,热爱网页,我更希望有一个更加自由、真正属于我自己的小站,或许并不是那么有名气,但至少能够让我为了它而加倍努力。。
=======================签 名 档=======================