#AtCoder Grand Contest 008 Contiguous Repainting
题意:小花有n个木箱 每个木箱有自己的值 小花现在玩一个游戏 要么给连续的k个木箱涂上白色 要么给连续的k个木箱涂上黑色 因为小花是一个高冷的女孩 所以她喜欢黑色 在进行一些没有顺序要求的涂色之后 问黑色木箱上的值的和最大是多少?
思路: 可以知道 在你的涂色中 你可以首先设想下先涂从第一个箱子开始的k个木箱 如果第一个木箱是正数 就涂成黑色的 如果是负数就涂成白色 然后涂从第二个箱子开始的k个箱子 此时应该隐约能够感觉到 你可以做到把所有的正数箱子涂成黑色 负数涂成白色 但是这里有一个特殊的就是最后一次涂 这k个要么全是黑色 要么全是白色 这个区间里面的箱子不能异色
所以此时我们就要考虑这个区间 当这个区间为白色时 就是这个区间里面的正数不选 也就是选择一个连续k个数的序列 其中的正数的和最小 当这个区间为黑色是 这个区间里面的负值就会被包括进去 此时我们需要选择一个连续k个数字的区间 使得这个区间里面的负数的和尽可能小 因为和越小 我们加的越少
代码如下: 啊啊 一万个BUG 已经连续好久好久没有写博客了 刚开始正式上课的几周 没有调整到自己适应的学习状态 而且训练还多 要改正!
#include<stdio.h> #include<iostream> using namespace std; long long n , k; long long a[100010] , sum[100010] , sum2[100010]; long long minn; long long maxx; int main() { while( scanf("%lld%lld" , &n , &k) != EOF ) { a[0] = 0; sum[0] = 0; sum2[0] = 0; minn = 100000000000001; maxx = -100000000000001; for(long long i=1; i<=n; i++) { scanf("%lld" , &a[i]); if(a[i] > 0) { sum[i] = sum[i-1]+a[i]; sum2[i] = sum2[i-1]; } else { sum2[i] = sum2[i-1]+a[i]; sum[i] = sum[i-1]; } if( i>=k ) { long long tmp = sum[i] - sum[i-k]; if(tmp < minn) { minn = tmp; } tmp = sum2[i]-sum2[i-k]; if(tmp > maxx) { maxx = tmp; } } } printf("%lld\n" , max(sum[n]+maxx , sum[n]-minn)); } return 0; } //Flower