USACO 2003 March Green - Best Cow Fences

题目

Farmer John's farm consists of a long row of N (1 <= N <= 100,000)fields. Each field contains a certain number of cows, 1 <= ncows <= 2000.

FJ wants to build a fence around a contiguous group of these fields in order to maximize the average number of cows per field within that block. The block must contain at least F (1 <= F <= N) fields, where F given as input.

Calculate the fence placement that maximizes the average, given the constraint.

链接(to poj)

翻译

农夫约翰的农场由 N 块田地组成,每块地里都有一定数量的牛,其数量不会少于 1 头,也不会超过 2000 头。

约翰希望用围栏将一部分连续的田地围起来,并使得围起来的区域内每块地包含的牛的数量的平均值达到最大。

围起区域内至少需要包含 F 块地,其中 F 会在输入中给出。

在给定条件下,计算围起区域内每块地包含的牛的数量的平均值可能的最大值是多少。

链接(to acwing)

题解

首先数学化题目。他是想说:

对于一个数列 A=(a1,a2,...,aN) ,求

maxl,r[1,N],rl+1F{1rl+1i=lrai}

从数据范围可知复杂度应当低于 O(n log n) 。首先考虑二分出平均数,再判断是否存在一个子段的平均数大于等于这个平均数。但是仔细一想,发现 “子段的平均数” 这个东西很难解决:它是比值定义式,既受总和影响,又被总数制约。而二分答案的 check 函数判断只能有一个限制。怎么办呢?

我们跳过比值定义式,从平均数的“移多补少”原理思考:我们把每个元素减去平均数,结果就删去了问题中的“平均数”字符串,发现现在要判断的问题变为:是否存在一个子段和非负。子段和……好解决啊!只需要考虑最大子段和即可,用双指针解决。

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>	//poj 不支持万能头……
using namespace std;
int n,f,c[100005];
double s[100005],l,r,mid;
bool check(double ave){
	double mn=0;	//mn 记录了最小前缀和…未必是第一个(有负数)!
	for(int i=1;i<=n;i++)s[i]=s[i-1]+c[i]-ave;
	for(int i=0,j=f;j<=n;i++,j++){	//双指针优化
		mn=min(mn,s[i]);
		if(s[j]-mn>=0)return true;
	}return false;
}
signed main(){
	scanf("%d%d",&n,&f);
	for(int i=1;i<=n;i++)scanf("%d",c+i),r=max(r,1.0*c[i]);
	while(r-l>1e-5){
		mid=(l+r)/2;
		if(check(mid))l=mid;
		else r=mid;
	}printf("%d\n",int(r*1000));
	return 0;
}

思维方式

ave 表示当前平均数。显然,它与任意一个子段都可以比较。

al+al+1+...+arrl+1ave

al+al+1+...+arrl+1ave0

al+al+1+...+arave(rl+1)0(rl+10)

(alave)+(al+1ave)+...+(arave)0

解决不了的问题转化成了可解决的!

posted @   robinyqc  阅读(81)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示