codeforces Ilya Muromets 2014 NEERC Southern Subregional Contest F dp

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


發佈了109 篇原創文章 · 獲贊 5 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章