【CodeChef】Reign

题面

分析

定义两个数组:\(sum1\)\(sum2\)

\(sum1[i]\)表示前\(i\)个数的最大区间和,\(sum2[i]\)表示后\(i\)个数的最大区间和。

最后从\(1\)\(n-k-1\)中找最大的两端区间和,即\(max(sum1[i]+sum2[i+k+1])\)

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define il inline
#define re register
#define maxn 100005
#define INF 0x7fffffff
#define tie0 cin.tie(0),cout.tie(0)
#define fastio ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;

template<typename T>inline void read(T &x){
	T f=1;x=0;char c;
    for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;
    for(;isdigit(c);c=getchar())x=x*10+(c^48);
    x*=f;
}

int n,k;
ll ans;
ll a[maxn],sum1[maxn],sum2[maxn];

int main(){
	int t;
	read(t);
	while(t--){
		memset(sum1,0,sizeof(sum1));
		memset(sum2,0,sizeof(sum2));
		ans=-INF;
		read(n),read(k);
		for(int i=1;i<=n;++i) read(a[i]);
		for(int i=1;i<=n;++i){
			if(sum1[i-1]>=0) sum1[i]=sum1[i-1]+a[i];
			else sum1[i]=a[i];
		}
		sum1[0]=-INF;
		for(int i=1;i<=n;++i)
			sum1[i]=max(sum1[i],sum1[i-1]);
		for(int i=n;i>=1;--i){
			if(sum2[i+1]>=0) sum2[i]=sum2[i+1]+a[i];
			else sum2[i]=a[i];
		}
		sum2[n+1]=-INF;
		for(int i=n;i>=1;--i)
			sum2[i]=max(sum2[i],sum2[i+1]);
		for(int i=1;i<n-k;++i) ans=max(ans,sum1[i]+sum2[i+k+1]);
		printf("%lld\n",ans);
	}
	return 0;
}
posted @ 2019-08-01 15:11  小蒟蒻hlw  阅读(114)  评论(0)    收藏  举报