HDU1028 Ignatius and the Princess III(DP)

题目点我点我点我


题意:找出整数n有多少种拆分方法。

思路:DP。dp[i][j]表示整数i拆分成最多j个数时的方案数。
状态转移分三种情况:
1.i < j时,dp[i][j]=dp[i][i],因为整数n最多也就能拆分成n个1.
2.i==j时,dp[i][j]=dp[i][j-1]+1,拆分成j-1个数的情况(dp[i][j-1])+全部拆成1的情况(1)。
3.i > j时,dp[i][j]=dp[i-j][j]+dp[i][j-1],dp[i-j][j]表示拆分出j个1后在拆分j个数,
dp[i][j-1]表示最多拆分j-1个数,也就是dp[i][j]前一个状态


/* ***********************************************
┆  ┏┓   ┏┓ ┆
┆┏┛┻━━━┛┻┓ ┆
┆┃       ┃ ┆
┆┃   ━   ┃ ┆
┆┃ ┳┛ ┗┳ ┃ ┆
┆┃       ┃ ┆
┆┃   ┻   ┃ ┆
┆┗━┓ 马 ┏━┛ ┆
┆  ┃ 勒 ┃  ┆      
┆  ┃ 戈 ┗━━━┓ ┆
┆  ┃ 壁     ┣┓┆
┆  ┃ 的草泥马  ┏┛┆
┆  ┗┓┓┏━┳┓┏┛ ┆
┆   ┃┫┫ ┃┫┫ ┆
┆   ┗┻┛ ┗┻┛ ┆
************************************************ */

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;

#define inf 0x3f3f3f3f
#define ll long long
#define ull unsigned long long
int dp[125][125];

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


int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n;
    while(~scanf("%d",&n))
    {
        solve(n);
        cout<<dp[n][n]<<endl;
    }
    return 0;
}


你可能感兴趣的:(HDU1028 Ignatius and the Princess III(DP))