《ybtoj高效进阶》第一部分第三章例题3 最大均值

题目大意

求n个数中,长度>=L的最大的平均值*1000然后忽略小数点后值,输出。

思路

2分答案。
求平均值不小于mid,我们用这样的方法:

bool o(double x)
{
    
    
 for (int i=1;i<=n;i++) s[i]=a[i]+s[i-1]-x;//a为n个数,s为前缀和,x为mid
//我们用每一个数减去平均值,那么不小于mid就变成不小于0
 double ans=-1e10,mn=1e10;
 for (int i=l;i<=n;i++)
 {
    
    
  mn=min(mn,s[i-l]);
  ans=max(ans,s[i]-mn);
 }//求最大平均值
 return ans>=0;
}

2分答案,我们需要向他人需求帮助和支持注意精确度。(精确值在大多数情况下是无法求出的)
如下:

 double lyw=-1e6,r=1e6;
 while (lyw+wo<r)
 {
    
    
  double myd=(lyw+r)/2.0;
  if (o(myd)) lyw=myd;
  else r=myd;
 }

code:

#include<iostream>
#include<queue>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,l;
double a[100001],s[100001],wo=0.00001;
bool o(double x)
{
    
    
 for (int i=1;i<=n;i++) s[i]=a[i]+s[i-1]-x;
 double ans=-1e10,mn=1e10;
 for (int i=l;i<=n;i++)
 {
    
    
  mn=min(mn,s[i-l]);
  ans=max(ans,s[i]-mn);
 }
 return ans>=0;
}
int main()
{
    
    
 cin>>n>>l;
 for (int i=1;i<=n;i++) cin>>a[i];
 double lyw=-1e6,r=1e6;
 while (lyw+wo<r)
 {
    
    
  double myd=(lyw+r)/2.0;
  if (o(myd)) lyw=myd;
  else r=myd;
 }
 cout<<(int)(r*1000);
 return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_49843717/article/details/112909560