HDU acm1028 整数划分 递归问题(递推)

我们用递归+记忆化的方法来解决普通整数划分问题:定义 f(n,m)为将整数n划分为一系列整数之和,其中加数

最大不超过m。

得到下面的递推关系式:

 当n==1 || m==1 只有一种划分,即 1 或者 1+1+1......+1

当m>n 显然,等价于 f(n,n)

当m==n 此时:我考虑加数包含m与否的两种情况:

1)划分不包含m,即f(n,m-1)---所有m-1的划分

2)划分包含 m,此时只有一种即 m

所以当m==n时,有 f(n,m)=f(n,m-1)+1

当m<n时,

1)包含m时,{m,x1,x2,x3....xi}此时 等价于 f(n-m,m)

2)不包含m时,显然f(n,m-1)

所以f(n,m)=f(n,m-1)+f(n-m,m)

采用记忆化技术优化复杂度:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 #define MAXN 130
 6 int num[MAXN][MAXN];
 7 int dp(int n,int k)
 8 {
 9     if(n==1||k==1)
10         return 1;
11     if(k>n)
12     {
13         k=n;
14         if(num[n][n]==-1)
15             return num[n][n]=dp(n,n);
16         else
17             return num[n][n];
18     }
19     else if(k==n)
20     {
21         if(num[n][k]==-1)
22             return num[n][k]=dp(n,k-1)+1;
23         else
24             return num[n][k];
25     }
26     else
27     {
28         if(num[n][k]==-1)
29             return num[n][k]=dp(n,k-1)+dp(n-k,k);
30         else
31             return num[n][k];
32     }
33 }
34 int main()
35 {
36     int n;
37     while(cin>>n)
38     {
39         memset(num,-1,sizeof(num));
40         cout<<dp(n,n)<<endl;
41     }
42     return 0;
43 }

 

posted @ 2015-03-11 20:16  fancy_boy  阅读(399)  评论(0编辑  收藏  举报