codeforces Ilya Muromets 2014 NEERC Southern Subregional Contest F dp

来源:互联网 发布:初学编程怎么学 编辑:程序博客网 时间:2024/04/26 08:18

传送门: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 200005int 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 = 0for x in a:Sum = Sum + xss.append(Sum)if k * 2 >= n:print Sumelse: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


0 0
原创粉丝点击