傳送門: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