F - Ilya Muromets Gym - 100513F

Силачом слыву недаром — семерых одним ударом!
From the Russian cartoon on the German fairy tale.
Ilya Muromets is a legendary bogatyr. Right now he is struggling against Zmej Gorynych, a dragon with n heads numbered from 1 to n from left to right.

Making one sweep of sword Ilya Muromets can cut at most k contiguous heads of Zmej Gorynych. Thereafter heads collapse getting rid of empty space between heads. So in a moment before the second sweep all the heads form a contiguous sequence again.

As we all know, dragons can breathe fire. And so does Zmej Gorynych. Each his head has a firepower. The firepower of the i-th head is f i.

Ilya Muromets has time for at most two sword sweeps. The bogatyr wants to reduce dragon’s firepower as much as possible. What is the maximum total firepower of heads which Ilya can cut with at most two sword sweeps?

Input
The first line contains a pair of integer numbers n and k (1 ≤ n, k ≤ 2·105) — the number of Gorynych’s heads and the maximum number of heads Ilya can cut with a single sword sweep. The second line contains the sequence of integer numbers f 1, f 2, …, f n (1 ≤ f i ≤ 2000), where f i is the firepower of the i-th head.

Output
Print the required maximum total head firepower that Ilya can cut.

Examples
Input
8 2
1 3 3 1 2 3 11 1
Output
20
Input
4 100
10 20 30 40
Output
100

题意:
一个序列,你可以选择长度为k的连续序列删除,可以删除两次(第一次删除完,剩下序列成为连续的)

思路:
一开始的错误思路是,选择最大的序列删掉,剩下的合并再删一次。但是第一次的删除会对第二次造成影响。所以正解是删掉两个长度为k的序列,且两个序列不交叉,这样包含错误思路的情况。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>

using namespace std;

const int maxn = 2e5 + 7;

int n,k;
int a[maxn],b[maxn];
int sum1[maxn],sum2[maxn];
int f1[maxn],f2[maxn];

int solve1() { //这一步是多余的
    int ans = 0;
    int l = 0,r = 0,mx = 0;
    for(int i = k;i <= n;i++) {
        if(mx < sum1[i] - sum1[i - k]) {
            mx = sum1[i] - sum1[i - k];
            l = i - k + 1;r = i;
        }
    }
    ans = mx;
    
    int cnt = 0;
    for(int i = 1;i <= n;i++) {
        if(i >= l && i <= r) {
            continue;
        }
        b[++cnt] = a[i];
        sum2[cnt] = sum2[cnt - 1] + b[cnt];
    }
    
    mx = 0;
    for(int i = k;i <= cnt;i++) {
        if(mx < sum2[i] - sum2[i - k]) {
            mx = sum2[i] - sum2[i - k];
        }
    }
    ans += mx;
    return ans;
}

int solve2() {
    for(int i = k;i <= n;i++) {
        f1[i] = max(f1[i - 1],sum1[i] - sum1[i - k]);
    }
    for(int i = n - k + 1;i >= 1;i--) {
        f2[i] = max(f2[i + 1],sum1[i + k - 1] - sum1[i - 1]);
    }
    int ans = 0;
    for(int i = k;i <= n - k;i++) {
        ans = max(ans,f1[i] + f2[i + 1]);
    }
    return ans;
}

int main() {
    scanf("%d%d",&n,&k);
    for(int i = 1;i <= n;i++) {
        scanf("%d",&a[i]);
        sum1[i] = sum1[i - 1] + a[i];
    }
    if(k * 2 >= n) {
        printf("%d\n",sum1[n]);
        return 0;
    }

    printf("%d\n",max(solve1(),solve2()));
    return 0;
}
原创文章 930 获赞 38 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/106057706