【AtCoder】AGC008 Contiguous Repainting

题目

传送门

题目大意

给你一个长度为 N ( N ≤ 1 0 5 ) N(N\leq10^5) N(N105)的序列 a a a ∣ a i ∣ ≤ 1 0 9 |a_i|\leq 10^9 ai109)和一个整数 K ( K ≤ N ) K(K\leq N) K(KN),一开始每个数都是白色的,每次可以将这个序列中的连续 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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值