【枚举】tyvj 1387 迷你火车头

题目链接:http://tyvj.cn/p/1387
题目大意:给你一个长度为n的数列,取三个长度为k的连续的一段数,使三部分的和最大

前几天似乎有人抢我生意……
所以我要抢回来………………

对于每个点,O(n)处理左侧的部分长度为k的一段数字最大和为多少,然后再O(n)处理出右侧的结果
直接枚举在哪个位置放置第二个火车,然后左边一个,右边一个……
时间复杂度O(n)
其实这道题就是APIO2009采油区域那道题的超简化版233

#include <iostream>
#include <cstdio>
using namespace std;
int a[100000];
int s1[100000];
int s2[100000];
int p1[100000];
int p2[100000];

int main()
{
    int n,m,ans = 0;
    scanf("%d",&n);
    for(int i = 1;i <= n;i ++)
    {
        scanf("%d",&a[i]);
        s1[i] = s1[i-1] + a[i];
    }
    scanf("%d",&m);
    for(int i = n;i ;i --)
    {
        s2[i] = s2[i+1] + a[i];
        p2[i] = max(p2[i+1],s2[i] - s2[i+m]);
    }
    for(int i = 1;i <= n;i ++)
        if(i <= m)
            p1[i] = s1[i];
        else
            p1[i] = max(p1[i-1],s1[i] - s1[i-m]);
    for(int i = 1;i <= n;i ++)
        ans = max(ans,s2[i] - s2[i+m] + p1[i-1] + p2[i+m]);
    cout << ans << endl;
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值