• hdoj 1028 Ignatius and the Princess III(区间dp)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1028

    思路分析:该问题要求求出某个整数能够被划分为多少个整数之和(如 4 = 2 + 2, 4 = 2 + 1 + 1),且划分的序列 2, 2 或者 2, 1, 1为单调非递增序列;

    使用动态规划解法:假设dp[i][j]表示整数i被划分的序列中最大值不超过j的所有的可能,则使用类似于0-1背包的思考方法;

    (1)如果i == j,则dp[i][j] = dp[i][j-1] + 1;

    (2)如果i > j,则根据整数i被划分的序列中是否有数值 j 分为两种情况:如果序列中含有数值j,则所有和为i - j且最大值不超过j-1的序列加上值 j即可构成和为i的序列;

     如果不含有j,则可能的所有不含有数值j且和为i的可能的序列数为 dp[i][j-1]个;

    综上:j > i时,dp[i][j] = dp[i][i]; j = i时,dp[i][j] = dp[i][j-1] + 1; j < i时,dp[i][j] = dp[i-j][j-1] + dp[i][j-1];

     

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    
    const int MAX_N = 120 + 20;
    long long dp[MAX_N][MAX_N];
    
    void Solve()
    {
        dp[0][0] = 1;
        for (int i = 0; i < MAX_N; ++ i)
        {
            for (int j = 1; j < MAX_N; ++ j)
            {
                if (j > i)
                    dp[i][j] = dp[i][i];
                else if (i == j)
                    dp[i][j] = dp[i][j-1] + 1;
                else
                    dp[i][j] = dp[i][j-1] + dp[i-j][j];
            }
        }
    }
    
    int main()
    {
        int number = 0;
    
        Solve();
        while (scanf("%d", &number) != EOF)
            printf("%d
    ", dp[number][number]);
        return 0;
    }
  • 相关阅读:
    循环结构
    位运算符
    Switch 选择结构
    if结构和逻辑运算符
    变量和运算符
    [luogu1090 SCOI2003] 字符串折叠(区间DP+hash)
    [luogu2329 SCOI2005] 栅栏(二分+搜索)
    [luogu 4886] 快递员
    [luogu4290 HAOI2008]玩具取名(DP)
    [luogu2624 HNOI2008]明明的烦恼 (prufer+高精)
  • 原文地址:https://www.cnblogs.com/tallisHe/p/4668165.html
Copyright © 2020-2023  润新知