勇士与公主(组合+完全背包)

Problem 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!"

看不懂英文可以直接看上面对数字4的拆解,简单的说就是对任意的数N,计算出有多少中拆解组合,注意4=3+1和4=1+3是一个组合。


Input

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.

输入N。


Output

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

输出拆解组合的数量P。


Sample Input

 
 

41020

 

Sample Output

 
 

542627


解题思路:

1、分解一下,采用背包的思想,求f(x),比如f(4),那么装背包时最大先用4来装,最大再用3,最大再用2...,最大用1。

2、这样可以建立一个方程,设 F(x, n)表示对于x,采用小于等于n的数字来拆解,有多少种解法

3、那么就有 f(x) = F(x, x),如f(6) = F(6, 6),表示用小于等于6的数字来拆解的解法数。

4、先看一个具体的例子,F(6, 1) 表示6全部用1拆解,F(6, 2)表示用1、2拆解,那么F(6, 2) = F(6, 1) + F(4, 2),所以状态转移方程:


F(x, n) = F(x, n-1) + F(x - n, n)


分析F(6, 2) = F(6, 1) + F(4, 2):

这里6先用1来拆,那么只剩下用2来拆的情况,用2拆的时候,因为已经固定了拆掉1个2,那么还剩下4要用小于等于2的数来拆。


处理的时候需要先后处理F(1,1), F(2,1)...F(6,1), F(2,2),...F(6,2),...,F(6,6)。

代码如下:

#include<bits/stdc++.h>
#include<string>
using namespace std;
int main()
{
    int a[200];
    int n;
    while(cin>>n)
    {
        memset(a,0,sizeof(a));
        a[0]=1;
        for(int i=1;i<=n;i++)
          for(int j=i;j<=n;j++)
          {
              a[j]+=a[j-i];
          }
        cout<<a[n];
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40630836/article/details/80469100
今日推荐