【JZOJ4809】挖金矿
Description
Solution
二分答案,把矩阵减去这个答案,然后要使选出来的数尽量大。
根据选出来的数和的非负性来判断缩小边界即可。
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define ll long long
#define N 100001
#define eps 0.00001
using namespace std;
int b[N];
int n,h;
double find(double x)
{
double s=0;
fo(i,1,n)
{
double p=0,q=-21474836470000.0;
fo(j,1,h)
{
p+=b[j+(i-1)*h];
q=max(q,p-j*x);
}
s+=q;
}
return s;
}
bool check(double x)
{
if(find(x)>=0) return true;
return false;
}
int main()
{
cin>>n>>h;
if(n==1)
{
int x;
cin>>x;
ll ans=x,t=1;
double q=x;
fo(i,2,h)
{
scanf("%d",&x);
ans+=x;
t++;
q=max(q,ans*1.0/t);
}
printf("%.4lf",q);
return 0;
}
int cnt=0;
double l=0,r;
fo(i,1,n)
fo(j,1,h) scanf("%d",&b[++cnt]),r=max(r,b[cnt]*1.0);
r+=eps;
while(l+eps<r)
{
double mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
printf("%.4lf",l);
}