题目链接:http://codeforces.com/problemset/problem/460/C
题意:给出一排花的高度,以及浇水的天数,还有一次最多浇多少连续的花,问这些天浇完花之后,令花高度的最小值最大。。
思路:当时什么想法都没有= =,然后就跪了,之后看的 http://www.cnblogs.com/zyfzyf/p/3926317.html 这个,讲的挺详细的= =,那个数组的想法真是很好(不知道线段树能不能过)。。。学习了~
那个数组的含义就是这朵花被浇了多少次,今天浇水了,那就加上,但是怎么知道到哪里这次就浇完了呢,他的做法是在浇完的那个的下一个减去这次浇的水,然后到那朵花的时候再加上那个数组的值(如果不考虑其他的浇水情况,应该是负的),就相当于减去了(语文渣。。自己大概理解下就行了,,理解起来貌似不难= =。。)~
请原谅我这混乱的变量命名。。。。
#include<cstdio>
#include<iostream>
#include<cstring>
#define ll long long
using namespace std;
ll n,m,w;
ll hh[200000];
ll add[200000];
bool ok(ll now){
memset(add,0,sizeof(add));
ll jia=0,done=0;
for(ll i=0;i<n;i++){
jia+=add[i];
if(hh[i]+jia<now){
done+=(now-jia-hh[i]);
if(done>m)return false;
add[i+w]-=(now-jia-hh[i]);
jia+=(now-jia-hh[i]);
}
}
return true;
}
int main(){
scanf("%d%d%d",&n,&m,&w);
for(ll i=0;i<n;i++){
scanf("%d",&hh[i]);
}
ll l=1,r=1100000000,m;
while(l<=r){
m=(l+r)>>1;
if(ok(m))l=m+1;
else r=m-1;
//cout<<l<<" "<<r<<endl;
}
printf("%d",r);
return 0;
}