OpenJudge 簡單的整數劃分問題(遞迴)
- 總時間限制:
- 100ms
- 記憶體限制:
- 65536kB
- 描述
-
將正整數n 表示成一系列正整數之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 ,k>=1 。
正整數n 的這種表示稱為正整數n 的劃分。正整數n 的不同的劃分個數稱為正整數n 的劃分數。 - 輸入
- 標準的輸入包含若干組測試資料。每組測試資料是一個整數N(0 < N <= 50)。
- 輸出
- 對於每組測試資料,輸出N的劃分數。
- 樣例輸入
-
5
- 樣例輸出
-
7
- 提示
5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+1
思路:
根據n和m的關係,考慮以下幾種情況:
(1)當n=1時,不論m的值為多少(m>0),只有一種劃分即{1};
(2)當m=1時,不論n的值為多少,只有一種劃分即n個1,{1,1,1,...,1};
(3)當n=m時,根據劃分中是否包含n,可以分為兩種情況:
(a)劃分中包含n的情況,只有一個即{n};
(b)劃分中不包含n的情況,這時劃分中最大的數字也一定比n小,即n的所有(n-1)劃分。
因此 f(n,n) =1 + f(n,n-1);
(4)當n<m時,由於劃分中不可能出現負數,因此就相當於f(n,n);
(5)但n>m時,根據劃分中是否包含最大值m,可以分為兩種情況:
(a)劃分中包含m的情況,即{m, {x1,x2,...xi}}, 其中{x1,x2,... xi} 的和為n-m,因此這情況下
為f(n-m,m)
(b)劃分中不包含m的情況,則劃分中所有值都比m小,即n的(m-1)劃分,個數為f(n,m-1);
因此 f(n, m) = f(n-m, m)+f(n,m-1);
綜上所述:
f(n, m)= 1; (n=1 or m=1)
f(n,m) = f(n, n); (n<m)
1+ f(n, m-1); (n=m)
f(n-m,m)+f(n,m-1); (n>m)
程式碼:
#include<iostream> using namespace std; int sp(int n,int m) { if(n==1||m==1) return 1; else if(n<m) return sp(n,n); else if(n==m) return sp(n,n-1)+1; else return sp(n,m-1)+sp(n-m,m); } int main() { int n; while(cin>>n) { cout<<sp(n,n)<<endl; } return 0; }