二分+贪心 二分最矮高度的最大值 每二分一个遍历看是否可达 可达low = mid+1不可达high = mid-1 可达的判断用贪心即可 改点长度不足时 在改点设置浇水点 同是在i+w设置断水 之后每个点都继承前一个点的浇水量 到i+w时减少i处浇的水即可
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#define sz 100000
#define ll long long
using namespace std;
int a[sz+2];
int dis[sz+2];
int n,m,w;
bool can(int x)
{
memset(dis,0,sizeof(dis));
int i,p,hs = m;
for(i = 1; i <= n; ++i)
{
dis[i] += a[i]+dis[i-1]-a[i-1];//dis[i-1]-a[i-1]继承前一点浇水量 用+=是为了即使断水
p = x-dis[i];
if(p > 0)
{
if(p > hs) return false;//当前水量不足返回false
hs -= p;
dis[i] += p;//设浇水点
if(i+w <= n) dis[i+w] -= p;//设断水点 防越界加个if
}
}
return true;
}
int main()
{
int i,l,r,mm,mid,ans;
scanf("%d %d %d",&n,&m,&w);
mm = 0;
a[0] = 0;
for(i = 1; i <= n; ++i)
{
scanf("%d",&a[i]);
mm = max(mm,a[i]);
}
l = 1,r = mm+m;//优化一下右界 加快
while(l <= r)
{
mid = (l+r)>>1;
if(can(mid))
{
ans = mid;
l = mid+1;
}else r = mid-1;
}
printf("%d\n",ans);
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/challengerrumble/article/details/47706517