传送门:NEERC Southern Subregional F
给定一段长度为n的数组,选出两段长度为k的子序列,使得总和最大
首先2*k>=n时,两段必能包含整个数组,因此输出总和即可。
否则,从第k个数开始向后扫,每一次求出到当前位置为止最大的k段和,然后与后面紧接的k个数求和,与当前得到的最大值比较。O(n)可解
/******************************************************
* File Name: f.cpp
* Author: kojimai
* Create Time: 2014年10月25日 星期六 15时48分29秒
******************************************************/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
#define FFF 200005
int a[FFF];
long long ss[FFF];
int main()
{
int n,k;
cin>>n>>k;
ss[0] = 0;
for(int i = 1;i <= n;i++)
{
cin>>a[i];
ss[i] = ss[i-1] + a[i];
}
long long ans = ss[k*2];
if(k*2>=n)
cout<<ss[n]<<endl;
else
{
long long tt = ss[k];
for(int i = k+1;i <= n-k;i++)
{
tt = max(tt,ss[i]-ss[i-k]);
ans = max(ans,tt + ss[i+k]-ss[i]);
}
cout<<ans<<endl;
}
return 0;
}
nn = raw_input()
nnn = map(int,nn.split())
n = nnn[0]
k = nnn[1]
s = raw_input()
a = map(int,s.split())
ss = [0]
Sum = 0
for x in a:
Sum = Sum + x
ss.append(Sum)
if k * 2 >= n:
print Sum
else:
tt = ss[k]
ans = ss[k * 2]
for i in range(k + 1,n - k + 1):
tt = max(tt,ss[i] - ss[i-k])
ans = max(ans,tt + ss[i+k] - ss[i])
print ans