【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);
}
posted @ 2016-10-05 16:02  sadstone  阅读(45)  评论(0编辑  收藏  举报