如,对于正整数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 }