1. 程式人生 > >遞迴求解整數的分劃問題

遞迴求解整數的分劃問題

整數劃分問題是演算法中的一個經典命題之一,有關這個問題的講述在講解到遞迴時基本都涉及到。

    所謂整數劃分,是指把一個正整數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;
 }