POJ2479 - Maximum sum (动规)

4 篇文章 0 订阅

题目链接 : poj2479 - Maximum sum

思路

题目要求的是,两段不相交的连续子列,使其加和最大。基础问题就是最大连续子列和,只要分别求得正序和逆序的最大和,然后枚举一边中间点,就可以得到结果。

最大连续子列和

解法有多种,这里用一种比较简单的动规的方法。另一种思路
num[i] 表示序列中第 i 个数字, F(i) 为以第 i 个数字结尾的序列中最大的和, 那么
 F(1)=num[1] { F(i)=F(i1)+num[i],    F(i1)>0 F(i)=num[i],    F(i1)<=0
根据题意,我们需要的 F(i) 是第 i 个数字之前的连续子列和的最大值,我们需要从头到尾更新一次

for(int i=2; i=n; i++) f(i) = max( f(i), f(i-2) );

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
const int inf = 0x7ffffff;

using namespace std;
int num[50010], s[50010], e[50010];

int main()
{
    int t, n, maxsum, sum;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        for(int i=1; i<=n; i++) scanf("%d", num+i);

        s[1] = num[1];
        for(int i=2; i<=n; i++)
        {
            if(s[i-1]>0) s[i] = s[i-1] + num[i];
            else s[i] = num[i];
        }
        for(int i=2; i<=n; i++) s[i] = max(s[i], s[i-1]);

        e[n] = num[n];
        for(int i=n-1; i>=1; i--)
        {
            if(e[i+1]>0) e[i] = e[i+1] + num[i];
            else e[i] = num[i];
        }
        for(int i=n-1; i>=1; i--) e[i] = max(e[i+1], e[i]);

        maxsum = -inf;
        for(int i=1; i<n; i++)
        {
            sum = s[i] + e[i+1];
            if(sum>maxsum) maxsum = sum;
        }

        printf("%d\n", maxsum);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值