标签:around 表示 clu cow 保留 amp order class lock
求均值的时候,不能/2
,而是要>>1
,这是因为/2
向0取整,>>1
向下取整,/2
在二分值域包含负数的时候无法正常工作。
正确写出二分的流程是:
mid
归属哪一半段。r=mid,l=mid+1,mid=(l+r)>>1
和l=mid,r=mid-1,mid=(l+r+1)>>1
的两个配套形式之一,保证每次的区间都能够缩小。l==r
,该值就是答案所在位置。确定精度eps
,若保留k为小数则取eps=1e-(k+2)
。
分支选择r=mid
或l=mid
之一即可。
精度不易确定或表示时,采用固定循环次数的二分方法。
函数必须具有严格单调性,不然三分法不再适用。
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.
0/1分数规划,二分答案判断即可,判断的方法是作差,判断有没有哪个区间和大于0,记录前缀和和前缀和最小值就行了。
时间复杂度\(O(N \log_2 ncows)\)。
然而二分边界设成[1,2000]会WA,设成[-1e6,1e6]才能AC。我思忖这均值咋地得弄成负数了。
#include<iostream>
#include<cstdio>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;
rg char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') w=-1;
ch=getchar();
}
while(isdigit(ch))
data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x){
return x=read<T>();
}
typedef long long ll;
co int MAXN=1e5+1;
double a[MAXN],b[MAXN],sum[MAXN];
int main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int N=read<int>(),L=read<int>();
for(int i=1;i<=N;++i)
read(a[i]);
co double eps=1e-5;
double l=-1e6,r=1e6;
while(r-l>eps){
double mid=(l+r)/2;
for(int i=1;i<=N;++i)
sum[i]=sum[i-1]+(b[i]=a[i]-mid);
double ans=-1e10,min_val=1e10;
for(int i=L;i<=N;++i){
min_val=std::min(min_val,sum[i-L]);
ans=std::max(ans,sum[i]-min_val);
}
if(ans>=0) l=mid;
else r=mid;
}
printf("%d\n",int(r*1000));
return 0;
}
标签:around 表示 clu cow 保留 amp order class lock
原文地址:https://www.cnblogs.com/autoint/p/10387700.html