3079 挖金矿

来源:互联网 发布:破解版软件网站 编辑:程序博客网 时间:2024/04/27 15:45

Task
N*m的矩形,每行取[ 1,m ]个数,求取出的最大平均值。

H*n<=1e5,a[i][j]∈[1,1e9]

Solution
二分的功能:
① 有序数组查找某值
② 假定解,判可行
③ 最大化最小值
最大化平均值
本题用2,4个功能。

sum1+sum2+*+sumn/num1+num2+***numn>=k
(sum1-k*num1)+(sum2-k*num2)+*(sumn-k*numn)>=0

顺序扫描这一行,找到sum-k*num最大的值,作为这一行的选择。

Double类型的二分技巧:循环100次,把mid赋值给l或r。l小于r+0.00001就可以停了,千万不要向我一样傻乎乎地循环了750次,导致TLE了。

常见的最大化平均值还有 枚举+贪心/dp 枚举分子,贪心分母 但是这不适用与于这一题。

code

const int M=1e5+5;vector<int>A[M];int n,m,mx;inline void input(){    int i,j,k;    rd(n);rd(m);    rep(i,0,n-1)rep(j,1,m)rd(k),A[i].pb(k),mx=max(mx,k);}inline bool check(db k){    int i,j;ll sum=0;    db ans=0.0,mx;    rep(i,0,n-1){           mx=-2e9;sum=0;        rep(j,0,m-1){            sum+=A[i][j];            mx=max(mx,(db)sum-1.0*1ll*k*(j+1));        }        ans+=mx;    }    return ans>=0;}inline void solve(){    int i,j,k=50;    db l=0,r=1.0*mx;    db mid;    while(k--){        mid=1.0*(l+r)/2;        if(check(mid))l=mid;        else r=mid;    }    printf("%.4lf\n",l);}int main(){    input();    solve();    return 0;}
1 0
原创粉丝点击