ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

01分数规划

2022-08-24 01:02:45  阅读:150  来源: 互联网

标签:分数 01 cheknum int res sum mid times 规划


01分数规划

经典例题:POJ2976

给定 \(n\) 个物品的价值 \(a\) 和 花费 \(b\) ,取其中的 \(k\) 个物品,求 \(\sum a[i] / \sum b[i]\) 的最大值。

题解

假设 \(\sum a[i] / \sum b[i] = x\) ,则:

当 \(x\) 不是最优解时,\(\sum a[i] / \sum b[i] \ge x\) 成立,则存在一种组合使 \(\sum(a[i]-x\times b[i]) > 0\) 成立

为了尽可能让解更大,我们需要尽可能使该式成立,这样就可以继续找更大的解。

为了尽可能使该式成立,我们需要取最大的 \(k\) 个 \((a[i]-x\times b[i])\) ,

若 \(\sum(a[i]-x\times b[i]) > 0\) 成立, \(x\) 就不是最优解 ;

也就是说不断二分 \(x\) 的值,就可以找到最优解:

设 \(cheknum=\sum(a[i]-x\times b[i])\) ,

若 \(cheknum > 0\) , 则 \(x\) 可以更大

若 \(cheknum=0\) , 则 \(x\) 是最优解

若 \(cheknum<0\) , 则 \(x\) 需要更小

代码:

bool chek(int x)
{
    rep(i,1,n) c[i]=a[i]-x*b[i];
    sort(c+1,c+n+1,cmp);//从大到小
    int res=0;
    rep(i,1,k) res+=c[i];
    return res >= 0;
    
}

void solv()
{
    int l=0,r=maxx;
    while(r - l > eps)
    {
        double mid = (r+l)/2;
        if(chek(mid)) l=mid;//更大
        else r=mid;//变小
    }
    printf("%lf",l);
}

标签:分数,01,cheknum,int,res,sum,mid,times,规划
来源: https://www.cnblogs.com/subtlemaple/p/16618390.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有