总结
二分这个算法就不说了,直接上一个题目吧,二分实数看算法竞赛指南上的题解勉强看懂,这题主要是让我求一个一个数组之中大于L长度的最大平均数。
书上大概都有,我就简单说下单调性吧。任意数列减去自己的平均数后总和为0如果一个数字小于平均值的话,减去这个数字后总和将会大于0,而如果大于平均值的话总和将会变成一个负数,由此可以看出平均值的单调性。
#include<stdio.h>
#include<algorithm>
using namespace std;
const double eps=1e-7;
int main()
{
int n,i,k;
double l,r,a[100006],b[100006];
scanf("%d %d",&n,&k);
for(i=1;i<=n;i++)
scanf("%lf",&a[i]);
l=-20000,r=20000;
while(l+eps<r)
{
double mid=(l+r)/2;
for(i=1;i<=n;i++) b[i]=a[i]-mid;
double sum[100006],minn=1e5,ans=-1e6;
sum[0]=0;
for(i=1;i<=n;i++)
{
sum[i]=b[i]+sum[i-1];
}
for(i=k;i<=n;i++)
{
minn=min(minn,sum[i-k]);
ans=max(ans,sum[i]-minn);
}
if(ans>=0) l=mid;
else r=mid;
}
int ans=r*1000;
printf("%d",ans);
return 0;
}
对于二分实数来说,一般eps=1e-(k+2),k为精确度,在判断时不能加一个eps!!!(蒟蒻亲测,加了eps后wa两发)