102. 最佳牛圍欄--------------------------思維(二分+套路題)

農夫約翰的農場由 N 塊田地組成,每塊地裏都有一定數量的牛,其數量不會少於1頭,也不會超過2000頭。

約翰希望用圍欄將一部分連續的田地圍起來,並使得圍起來的區域內每塊地包含的牛的數量的平均值達到最大。

圍起區域內至少需要包含 F 塊地,其中 F 會在輸入中給出。

在給定條件下,計算圍起區域內每塊地包含的牛的數量的平均值可能的最大值是多少。

輸入格式
第一行輸入整數 N 和 F ,數據間用空格隔開。

接下來 N 行,每行輸出一個整數,第i+1行輸出的整數代表,第i片區域內包含的牛的數目。

輸出格式
輸出一個整數,表示平均值的最大值乘以1000再 向下取整 之後得到的結果。

數據範圍
1≤N≤100000
1≤F≤N
輸入樣例:
10 6
6
4
2
10
3
8
5
9
4
1
輸出樣例:
6500

解析:
二分答案。
一般求平均值最大。那我們可以用原數組值-平均值,然後在維護一個前綴和。如果某一段的前綴和>=0 && 長度>=f 說明符合題意,讓l=mid 繼續尋找最大值

某一段的前綴和>=0 就相當於 sum[j]>=sum[i] 。sum[i] 就相當於[1~j-1 ]這段區間的最小值

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10000;
double a[N],sum[N];
int n,f;
bool check(double x)
{
	for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]-x;
	double minn=0;
	for(int i=f,j=0;i<=n;i++,j++)
	{
		minn=min(minn,sum[j]);
		if(sum[i]>=minn) return true;
	}
	return false;
}
int main()
{
	scanf("%d %d",&n,&f);
	double l=0,r;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		r=max(r,a[i]);
	}
	while(r-l>1e-5)
	{
		double mid=(l+r)/2;
		if(check(mid)) l=mid;
		else r=mid;
	}
	cout<<(int)(r*1000)<<endl;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章