挖金矿

来源:互联网 发布:Js写table 编辑:程序博客网 时间:2024/06/02 08:43

这里写图片描述
这里写图片描述
做的第二个01分数规划,二分答案,化简式子移下项就搞定,然后就是怎样验证了,验证理解简单却难想,看代码就能看懂。
还有需要注意的是原题数据对上下边界的要求很高,需额外开大些。
代码如下

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define ll long longusing namespace std;const int size = 2000010;int n,h;ll sum[size];ll a[size];double l,r;void st(){    scanf("%d%d",&n,&h);    for(int i = 1 ; i <= n ; i ++)        for(int j = 1 ; j <= h ; j ++)            scanf("%lld",&a[(i-1)*h+j]) , r = max((double)a[(i-1)*h+j],r);    for(int i = 1 ; i <= n ; i ++)        for(int j = 1 ; j <= h ; j ++)            if(j == 1)                sum[(i-1)*h+j] = a[(i-1)*h+j];            else                sum[(i-1)*h+j] = sum[(i-1)*h+j-1] + a[(i-1)*h+j];}bool check(double mid){    double mx_sum = 0;    for(int i = 1 ; i <= n ; i ++)    {        double mx = -214748364711ll;        for(int j = 1 ; j <= h ; j ++)            mx = max(mx,sum[(i-1)*h+j]-j*mid);        mx_sum += mx;    }    if(mx_sum >= 0)        return true;    return false;}int main(){    st();    while(r - l > 0.00001)    {        double mid = (l + r) / 2.0;        if(check(mid))            l = mid;        else            r = mid;    }    printf("%.4lf\n",l);    return 0;}/*4 34 3 35 1 62 6 13 2 9*/
0 0
原创粉丝点击