LA 3971 Assemble(组装电脑 最小值最大 二分答案)

来源:互联网 发布:webrtc 最新源码下载 编辑:程序博客网 时间:2024/04/28 13:41

二分答案这个思想用过了。非常好的思想,题意是你有b元钱 需要组装一台电脑

先给出n和b 分别代码有n个配件可供选择 一共有b元钱

接下来n行 每行描述一个配件 种类名 名称 价格 品质因子 品质因子越大越好 种类和名称是字符串

要求每个种类选一个

 

输出最小品质因子的最大值。

这个值肯定在品质因子的最小值和最大之间 二分这个答案

每次二分到的mid 查看是否ok ok就表示 对于每种配件 选择一个 比mid大或者等于mid的配件 price总数是不超过b的 也就是这种是可行的 但是不一定是最优的

最优还要考二分

这里用到的二分和平时常用的二分模板不一样 首先while循环里 是low<high  不是<= 否则一直死循环。。

因为我们最后得到的答案是low 而且mid 也用  mid=low+(high-low+1)/2; 的方法来求

所以 low 肯定是ok的 如果 新的mid 不ok low 也不能变。只能更新hign

因为如果mid不ok 肯定得比mid小的 所以high是mid-1


还有对于每种配件sort 按照价格排序 贪心思想 尽量找 品质满足 而且价格便宜的 如果没找到 直接return false;

最后看sum


其中用map <string,int> 把种类转换成数字 还有配件的名字在这里是没用的。因为没有要求选用了哪些配件

wa了一次 又是忘记把中间输出注释掉了。。。。


#include<iostream>#include<cstdio>#include<vector>#include<string>#include<map>#include<algorithm>using namespace std;const int maxn=1005;struct Node{    int quality;    int price;    bool operator <(const Node & n)const    {        return price<n.price;    }};map<string,int> mp;vector<Node> vec[maxn];int cnt,n,b;bool ok(int m){    int i,j,sum=0;    for(i=0;i<cnt;++i)    {        bool f=0;        for(j=0;j<vec[i].size();++j)        {            if(vec[i][j].quality>=m)            {                f=1;                sum+=vec[i][j].price;                if(sum>b)                return false;                break;            }        }        if(!f)        return false;    }    return true;}int main(){    int T;scanf("%d",&T);    char kind[25],name[25];    Node node;    while(T--)    {        mp.clear();        for(int i=0;i<maxn;++i)        vec[i].clear();        cnt=0;        scanf("%d %d",&n,&b);        int minquality=1<<29,maxquality=-1;        for(int i=0;i<n;++i)        {            scanf("%s %s %d %d",kind,name,&node.price,&node.quality);            if(!mp.count(string(kind)))            mp[string(kind)]=cnt++;            int k=mp[string(kind)];            vec[k].push_back(node);            minquality= min(minquality,node.quality);            maxquality= max(maxquality,node.quality);        }        for(int i=0;i<cnt;++i)        sort(vec[i].begin(),vec[i].end());        int low=minquality,high=maxquality,mid;        while(high>low)        {            mid=low+(high-low+1)/2;            if(ok(mid))            low=mid;            else            high=mid-1;        }        printf("%d\n",low);    }    return 0;}

 

原创粉丝点击