遞迴求解整數的分劃問題
阿新 • • 發佈:2018-12-31
整數劃分問題是演算法中的一個經典命題之一,有關這個問題的講述在講解到遞迴時基本都涉及到。
所謂整數劃分,是指把一個正整數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; }