整数划分问题是算法中的一个经典命题之一,有关这个问题的讲述在讲解到递归时基本都涉及到。
所谓整数划分,是指把一个正整数n写成如下形式:
n=m1+m2+m3+....+mi;(其中mi为正整数,并且1<=mi<=n),则{m1,m2,m3,....,mi}为n的一个划分。
如果{m1,m2,m3,....,mi}中的最大值不超过m,即max{m1,m2,m3,....,mi} <= m,则称它属于n的一个m划分。这里我们记n的m划分的个数为f(n,m);
例如当n=4时,它有5个划分:{4}、{3,1}、{2,2}、{2,1,1}、{1,1,1,1};
注意:4=1+3和4=3+1被认为是同一个划分。
如,对于正整数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
现在的问题是,对于给定的正整数n,编写算法打印所有划分。
编程思想:简单递归。
CODE:
#include<stdio.h>
#include<iostream>
#include<cstring>
#include<math.h>
#include<algorithm>
using namespace std;
void f(int n,int a[],int k)
{
if(n<=0)
{
printf("%d",a[0]);
for(int i=1;i<k;i++)
{
printf("+%d",a[i]);
}
puts("");
}
for(int i=n;i>0;i--)
{
if(k>0&&i>a[k-1]) continue;
a[k]=i;
f(n-i,a,k+1);
}
}
int main()
{
int n;
int a[1000];
while(scanf("%d",&n)!=EOF)
{
f(n,a,0);
}
return 0;
}