最佳牛围栏

求长度不小于L,平均数最大的最大子段和

书中的问题: 为什么答案具有单调性?

  1. 平均数越大越好

  2. 我们二分一个平均数 如果找不到一个字段比这个平均数大 那么更大的平均数肯定也找不到

  3. 如果找到了的话 那么就可以尝试更大的平均数

  4. 减去平均数 转化为字段的正负

  5. 平均数用二分

  6. 子段求和转化为前缀和

  7. 二元问题 两个变量相互依存 注意决策集合大小变化

  8. 将最值问题转化为寻找条件尽可能满足最值

bool check(double mid)
{
	double ans=-1e10,minn=1e10;
	for(rint i=1;i<=n;i++) b[i]=a[i]-mid;
	for(rint i=1;i<=n;i++) sum[i]=sum[i-1]+b[i];
	for(rint i=L;i<=n;i++)
	{
		minn=min(minn,sum[i-L]);
		ans=max(ans,sum[i]-minn);
	}
	return ans>=0;
}

double work()
{
	double l=0,r=1e4;
	while(r-l>eps)
	{
		double mid=(l+r)/2;
		if( check(mid)) l=mid;
		else r=mid;
	}
	return r;
}

int main()
{
	n=read(); L=read();
	for(rint i=1;i<=n;i++)  a[i]=read();

	printf("%d",(int)(work()*1000));
	return 0;
}

注意:
精度问题: 可以考虑返回l还是r 或者增加或者减少一个非常小的量

posted @ 2022-01-20 14:33  __iostream  阅读(30)  评论(0)    收藏  举报