您的位置:首页 > Web前端

Best Cow Fences 二分搜索加dp求大于一指定长度的最大值

2010-04-17 22:00 344 查看
Description
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.

Input
* Line 1: Two space-separated integers, N and F.

* Lines 2..N+1: Each line contains a single integer, the number of cows in a field. Line 2 gives the number of cows in field 1,line 3 gives the number in field 2, and so on.

Output
* Line 1: A single integer that is 1000 times the maximal average.Do not perform rounding, just print the integer that is 1000*ncows/nfields.

Sample Input
10 6
6
4
2
10
3
8
5
9
4
1

Sample Output
6500
#include <iostream>
#include <algorithm>
using namespace std;
#define inf 0x7fffffff
#define maxn 100001
#define EPS 1e-6
double a[maxn],s[maxn];
int n,m;
bool check(double val)
{
double b=s[m-1]-m*val;
for(int i=m;i<n;i++)
{
double s1=b + a[i] - val;//下一个
double s2=s[i]- s[i-m] - m*val;//当前
b=max(s1,s2);
if(b>=EPS)return true;
}
return b>=EPS;
}
double binary_Research(double minl,double maxl)
{
double l,r;
l=minl;
r=maxl;
while(r-l>=EPS)
{
double mid=(l+r)/2.0;
if(check(mid))l=mid;
else r=mid;
}
return l;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
double minl=inf;
double maxl=-inf;
for(int i=0;i<n;i++){
scanf("%lf",&a[i]);
a[i]*=1000.0;
if(a[i]>maxl)maxl=a[i];
if(a[i]<minl)minl=a[i];
}
s[0]=a[0];
for(int i=0;i<n;i++)
s[i]=s[i-1]+a[i];
int cnt=(int)(binary_Research(minl,maxl)+0.2);
cout<<cnt<<endl;
}
}

关于这个动规思想主要是用二分去寻找恰当的值

然后求在某一段上的满足条件的段

用dp的式子就是s[m]=max(s[m-1]+a[i],s[i]-s[i-m]);

举个例子来说,有一串数:1 2 3 4 5 6 7 8

假设长度至少需要3,那么就是s[3]就是6,这个是可以确定的

然后下一个我们的长度如果需要正好是3,那么可能的取值就是

{(1 2 3) ,(2 ,3 ,4), (3,4,5)...(6,7,8));

但是如果是大于3呢?

假设可能的长度为4或3

那么当前的子问题是(1,2,3,4)和(2,3,4)的那个平均数大的问题

由上递推可得,最后的一定为最优解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: