首页 > 代码库 > HDU1024 经典DP+状态压缩

HDU1024 经典DP+状态压缩

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1024

题目大意:

求n个数分成m个子区间的最大和

推导过程已写在代码中

#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
#define oo 0x3f3f3f3f
int dp[1000010], maxn[1000010], nums[1000010];
///dp[i][j]表示前j个数分成i段的并且包含nums[i]的最大值,所以dp[i][j] = max( dp[i][j-1],max(dp[i-1][1~j-1]) )+nums[j]
///可以发现第一维是可以优化的,分成i-1段的取1~j-1区间的最大值是可以在计算中提前存下来的
///即maxn[i]表示在分成 (当前段数-1)段时的1~j-1区间的最大值
///这样优化后可知,来源有两种
///dp[j] = max(maxn[j-1](上一次分段), dp[j-1](本次分段,直接合并到最后))+nums[i];
///同时每一步得到dp[j]即更新Maxn(代表1~当前区间)的最大值
int main()
{
    int m, n;
    while(scanf("%d %d", &m, &n)!=EOF)
    {
        for(int i=1; i<=n; i++)
        {
            scanf("%d", &nums[i]);
            maxn[i] = 0;
            dp[i] = 0;
        }

        int Maxn;
        for(int i=1; i<=m; i++)
        {
            Maxn = -oo;
            for(int j=i; j<=n; j++)
            {
                dp[j] = max(maxn[j-1], dp[j-1])+nums[j];
                maxn[j-1] = Maxn;
                Maxn = max(Maxn, dp[j]);
            }
        }
        printf("%d\n", Maxn);
    }
    return 0;
}

 

HDU1024 经典DP+状态压缩