Gym 100513F - Ilya Muromets

Ilya Muromets is alegendary bogatyr. Right now he is struggling against Zmej Gorynych, a dragonwith n headsnumbered from 1 to n from left to right.

Making one sweep of swordIlya Muromets can cut at most k contiguous heads ofZmej Gorynych. Thereafter heads collapse getting rid of empty space betweenheads. So in a moment before the second sweep all the heads form a contiguoussequence again.

As we all know, dragons canbreathe fire. And so does Zmej Gorynych. Each his head has a firepower. Thefirepower of the i-th head is fi.

Ilya Muromets has time forat most two sword sweeps. The bogatyr wants to reduce dragon's firepower asmuch as possible. What is the maximum total firepower of heads which Ilya cancut with at most two sword sweeps?

Input

The first line contains apair of integer numbers n and k (1 ≤ n, k ≤ 2·105) — thenumber of Gorynych's heads and the maximum number of heads Ilya can cut with asingle sword sweep. The second line contains the sequence of integer numbersf1, f2, ..., fn (1 ≤ fi ≤ 2000), where fi is the firepower ofthe i-th head.

Output

Print the required maximumtotal head firepower that Ilya can cut.

Sample test(s)

input

8 2
1 3 3 1 2 3 11 1

output

20

input

4 100
10 20 30 40

output

100

 

思路:

首先我是想先求一边连续K个数最大和,再把剩下的合并,再求一遍最大和

接着发现其实可以同时求两段K个数最大和


程序:
#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <cstring>
#include <cstdio>
#include <stack>
#include <cstdlib>
#include <cmath>
using namespace std;

const int N = 200005;

int max(int a, int b)
{
	if (a > b)
		return a;
	else
		return b;
}

struct node
{
	int x, y;
};

int f[N * 2];
__int64 sum[N * 2];

int main()
{
	int n, k;
	scanf("%d %d", &n, &k);

	memset(f, 0, sizeof(f));
	memset(sum, 0, sizeof(sum));

	int i;
	for (i = 1; i <= n; i++)
	{
		scanf("%d", &f[i]);
		sum[i] = sum[i - 1] + f[i];
	}


	if (2 * k >= n)
	{
		printf("%I64d\n", sum[n]);
		return 0;
	}

	__int64 maxx = 0, maxy = 0;
	for (i = k; i <= n; i++)
	{
		if (sum[i] - sum[i - k] >= maxx)
		{
			maxx = sum[i] - sum[i - k];
		}
		maxy = max(maxy, maxx + sum[i + k] - sum[i]);
	}
	
	printf("%I64d\n", maxy);

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值