Ignatius and the Princess III - 拆分数-动态规划(dp)

---恢复内容开始---

2017-08-10 20:00:45

writer:pprp

拆分数:

  把正整数n拆分成k个正整数之和的方案数;

问题转换:将1转化为2

  1、把n表示成m个正整数之和的方案数

  2、把n表示成不超过m的正整数之和的方案数 

两者答案相同:解释Ferrers图

用dp来做,dp[i][j]的意思是 i 表示成 不超过 j 的方案数

边界条件:

  dp[0][j] = 1 , dp[[i][1] = 1 , dp[1][j] = 1;

状态转移:

  dp[i][j] = dp[i][j-1]+dp[i-j][j];  

  n个数划分成不超过m的整数的方案,若最大数为m,那么把最大数去掉,等价于把n-m分成不超过m的整数的方案,

  若最大数不是m,那么等价于把n分成不超过m-1的方案数


 

代码如下:

 

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>

using namespace std;

const int maxn = 130;
int dp[maxn][maxn];

void DP()
{
    for(int i = 1; i < maxn ; i++)
    {
          dp[i][1] = dp[1][i] = dp[0][i] = 1;
    }
    for(int i = 2 ; i < maxn ; i++)
    {
        for(int j = 2 ; j < maxn ; j++)
        {
              if(i >= j)
                  dp[i][j] = dp[i][j-1]+dp[i-j][j];
              else
                  dp[i][j] = dp[i][i];
        }
    }
}

int main()
{
    int n;
    memset(dp,0,sizeof(dp));

    DP();

    while(cin >> n)
    {
        cout << dp[n][n] << endl;
    }
    return 0;
}

 

posted @ 2017-08-10 20:25  pprp  阅读(378)  评论(0编辑  收藏  举报