hdu 1024 Max Sum Plus Plus

题意:在一个序列中,求出m个不相交的子序列,使这m个序列的和最大。

题意好理解,但递归方程的表示有些令我迷茫惊恐看了下大牛们的题解,在这里说一下我的看法。

这里我结合代码来说一下:

 dp[i][j]=Max(dp[i][j-1]+a[j] , max( dp[i-1][k] ) + a[j] ) 0<k<j)
dp[i][j]             表示前j个数分成i组时的最大值;

dp[i][j-1]+a[j]   表示(前i-1个数分成i组的最大值)+(第j个数),这意味着第j个数也属于第i组;

max(dp[i-1][k])+a[j] 0<k<j   表示(j前面的所有序列中分成i1组和最大的一个)+(第j个数),这意味着从第j个数开始为新的一组;然后加上前面i-1组的一共i组。


因为求max(dp[i-1][k])+a[j] 0<k<j 会因出现for循环而超时,所以考虑在分成i-1组的递归时就求出max(dp[i-1][k])0<k<j,

于是有下面公式

dp[j]=max(dp[j-1]+a[j],b[j-1]+a[j]);(因为上面dp[i][j-1]+a[i]仅用到当前行的dp值,所以完全可以用一维dp数组表示

b[j-1]表示上面的max(dp[i-1][k])0<k<j。

请结合代码看

#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
using namespace std;
int a[1000010],dp[1000010],b[1000010];
int main()
{
    int m,n,num=0,maxx;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        for(int i=1; i<=n; i++)
            cin>>a[i];
        memset(dp,0,sizeof(dp));
        memset(b,0,sizeof(b));
        for(int i=1; i<=m; i++)
        {
            maxx=-(0x7fffffff);
            for(int j=i; j<=n; j++)
            {
                dp[j]=max(dp[j-1]+a[j],b[j-1]+a[j]);
                b[j-1]=maxx;
                if(dp[j]>maxx)
                {
                    maxx=dp[j];
                }
            }
        }
        cout<<maxx<<endl;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值