递归之整数划分问题
一、问题描述
将正整数n表示成一系列正整数之和:
n=n1+n2+...+nk;(其中n1>=n2>=...>=nk)
如6:共有11种
6=6;
6=5+1;
6=4+2; 6=4+1+1;
6=3+3; 6=3+2+1; 6=3+1+1+1;
6=2+2+2; 6=2+2+1+1; 6=2+1+1+1+1;
6=1+1+1+1+1+1;
如5:共有7种
5=5;
5=4+1;
5=3+2; 5=3+1+1;
5=2+2+1; 5=2+1+1+1;
5=1+1+1+1+1;
二、问题分析
从整数划分的例子中,可以采用递归的思想去解决。如整数6,它的第一步是从6-1;第二步则是从第一步的差以及小于第一步的数开始,依次类推,直至这些整数之和为6.
如6=5+1;第一步是5,第一步的差是6-5=1,所以第二步从第一步5和第一步的差1两者较小数1开始递减;
6=1+1+1+1+1+1,第一步是1,第一步的差是6-1=5,所以第二步从第一步1和第一步的差5两者较小数1开始递减,这样后面只能是1,这样才能保证划分的规律性。
三、程序设计
#include<iostream>
using namespace std;
int num=0; //记录划分的类别数
void int_part(int n,int j) //n记录整数的剩余数,j记录上一步的数,确保是按照递减的数累加
{
if(n==0) //如果刚好分配完,则数目加1
{
num++;
return;
}
for(int i=n<j?n:j;i>0;i--) //i取两者之间的小值,利用条件表达式
int_part(n-i,i);
}
void main()
{
int n;
cout<<"请输入一个正整数:";
cin>>n;
int_part(n,n); //整数划分函数,初始都设为n
cout<<"划分的数目是:"<<num<<endl;
while(1);
}
四、程序结果