题目
题目大意
给你一个长度为 N ( N ≤ 1 0 5 ) N(N\leq10^5) N(N≤105)的序列 a a a( ∣ a i ∣ ≤ 1 0 9 |a_i|\leq 10^9 ∣ai∣≤109)和一个整数 K ( K ≤ N ) K(K\leq N) K(K≤N),一开始每个数都是白色的,每次可以将这个序列中的连续 K K K个数涂成白色或黑色,你可以进行任意次操作,最后将黑色的数加起来,问最大的和是多少。
思路
不论怎么涂,最后总会有一段连续的 K K K个数是同种颜色(最后一次涂的 K K K个数),除去这些数,其他的数你可以任意设置它们的颜色(例如: N = 5 , K = 3 N=5,K=3 N=5,K=3, a = 1 , 2 , 3 , 4 , 5 a=1,2,3,4,5 a=1,2,3,4,5,我想把 a 4 = 4 a_4=4 a4=4涂成黑色,就先把 a 2 , 3 , 4 a_{2,3,4} a2,3,4涂黑,再把 a 1 , 2 , 3 a_{1,2,3} a1,2,3涂白即可)。
于是直接枚举序列中的连续 K K K个数,把除了这 K K K个数之外所有的正数涂黑,再看这 K K K个数涂白(和为负数)还是涂黑(和为正数),统计答案。
代码
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 100000
int N,K;
int A[MAXN+5];
long long SumP[MAXN+5],Sum[MAXN+5];//分别是正数的前缀和、一共的前缀和
int main(){
scanf("%d%d",&N,&K);
for(int i=1;i<=N;i++){
scanf("%d",&A[i]);
Sum[i]=Sum[i-1]+A[i];
SumP[i]=SumP[i-1]+(A[i]>0)*A[i];
}
long long Ans=0;
for(int i=K;i<=N;i++){
long long tmp=Sum[i]-Sum[i-K];//目前K个数的和
tmp=(tmp>0)*tmp+SumP[i-K]+SumP[N]-SumP[i];//如果目前K个数的和为正数,就把他们涂黑
Ans=max(Ans,tmp);
}
printf("%lld",Ans);
}