ACM: HDU 1028 Ignatius and the Princess III-DP

时间:2022-09-11 04:48:53
 HDU 1028 Ignatius and the Princess III

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

"Well, it seems the first problem is too easy. I will let you know how foolish you are later." feng5166 says.

"The second problem is, given an positive integer N, we define an equation like this: 
  N=a[1]+a[2]+a[3]+...+a[m]; 
  a[i]>0,1<=m<=N; 
My question is how many different equations you can find for a given N. 
For example, assume N is 4, we can find: 
  4 = 4; 
  4 = 3 + 1; 
  4 = 2 + 2; 
  4 = 2 + 1 + 1; 
  4 = 1 + 1 + 1 + 1; 
so the result is 5 when N is 4. Note that "4 = 3 + 1" and "4 = 1 + 3" is the same in this problem. Now, you do it!" 

Insilput

The input contains several test cases. Each test case contains a positive integer N(1<=N<=120) which is mentioned above. The input is terminated by the end of file. 

Output

For each test case, you have to output a line contains an integer P which indicate the different equations you have found. 

Sample Input

4
10
20

Sample Output5

42
627
/*/
思路有点像模拟,先从小的开始排序,用样例1来说 4的位置可以只放1 {1,1,1,1};① 4的位置也可以放一个2 {2,1,1};这时候剩下2个位置,这状态可以做为一个往2个位置里面再去放东西来看 2的位置可以只放1 {1,1}; 对应的4个位置为 {2,1,1};② 2的位置也可以放一个2 {2}; 对应的4个位置为 {2,2};③ 4的位置可以放一个3 {3,1}; ④ 4的位置可以只放一个4 {4}; ⑤ 这就是整个过程.【现在放图】 ACM:  HDU 1028 Ignatius and the Princess III-DP 实现过程:
ACM:  HDU 1028 Ignatius and the Princess III-DP 对于这个过程,如果一开始就是前面往后面去推的话,很容意发现,前面的插小空的状态是可以保存的,用dp保存每一个从x个填满y长度的方法个数。 如果y==x,那就说明已经填满了,最大的填放方法已经放完了。 又因为如果y>x的话,不可能放下去,就直接复制前面的种类次数就是的了,也就是:dp[x][y]=dp[x][x];//不可能往小位置里塞入大的数 直接结果就是dp[n][n]; AC代码:
/*/
#include"map"
#include"cmath"
#include"string"
#include"cstdio"
#include"vector"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
typedef long long LL;
const int MX=202;
#define memset(x,y) memset(x,y,sizeof(x))
#define FK(x) cout<<"【"<<x<<"】"<<endl
int n,dp[MX][MX]; int main() {
memset(dp,0);
for(int i=1; i<MX; i++) { //把x,y=1的情况都标出来,为1。
dp[i][1]=dp[1][i]=1;
}
for(int x=2; x<MX; x++) {
for(int y=2; y<MX; y++) {
if(x<y) dp[x][y]=dp[x][x];//不可能往小位置里塞入大的数
if(x==y)dp[x][y]=dp[x][y-1]+1; //加上放入最大的数的一次。
if(x>y) dp[x][y]=dp[x][y-1]+dp[x-y][y];/* dp[x-y][y] 往x-y大小里面插入y的可能的次数*/
}/* dp[x][y-1] 前面的次数*/
}
while(~scanf("%d",&n))
printf("%d\n",dp[n][n]);
return 0;
}