如,對於正整數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+1
現在的問題是,對於給定的正整數n,程序輸出該整數的拆分種類數。
DP思路:
n = n1 + n2 + n3 + n4 + .... + nk
狀態表示:將n划分為k個數相加的組合方案數記為 q(n,k)。(相當於將n個蘋果放入k個盤子)
狀態轉移:
(1)若k>n,則盤子數大於蘋果數,至少有n-k個空盤子,可以將其拿掉,對組合方案數無影響。
q(n,k) = q(n,n)
(2)若k<=n,則盤子數小於等於蘋果數,則分為兩種情況
1.至少有一個盤子空着:q(n,k) = q(n,k-1)
2.所有盤子都不空:q(n,k) = q(n-k,k)
q(n,k) = q(n,k-1) + q(n-k,k)
1 //dp非遞歸的方法 2 #include <iostream> 3 #include <stdio.h> 4 5 using namespace std; 6 7 int main() 8 { 9 int n, i, j, dp[121][121]; 10 for(i = 1; i < 121; i++) 11 { 12 for(j = 1; j < 121; j++) 13 { 14 if(i == 1 || j == 1) 15 dp[i][j] = 1; 16 else if(i > j) 17 dp[i][j] = dp[i][j-1] + dp[i-j][j]; 18 else if(i ==j) 19 dp[i][j] = dp[i][j-1] + 1; 20 else 21 dp[i][j] = dp[i][i]; 22 } 23 } 24 while(scanf("%d", &n) != EOF) 25 { 26 cout << dp[n][n] << endl; 27 } 28 return 0; 29 }