• 组装电脑 LA 3971 二分答案


    题目:
    给定电脑的n(n<1000)个配件,每个配件有类型,名字(没用的信息),价格和品质因子。要求每种类型的配件各买一个用于组装电脑,总价格不超过b元。求所有可能的方案中品质因子最差的那个配件的品质因子最大能是多少。
    分析:
    看着这数据,觉得暴力也可做,枚举每个品质因子,找出满足要求的最大的。但如果数据大一点,就不能这么暴力了,就要二分答案去找最优解了。
    具体实现,就是把每种类型的配件都保存到一个vector中,买的时候从这里面选择一个品质因子比最小的要大的品质因子且价格最低的配件,然后把所有的加起来,判断一下是不是<=b就好。

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #include<map>
    #include<string>
    using namespace std;
    typedef pair<int,int>pii;
    #define pb push_back
    #define mpi make_pair
    map<string,int>mp; //每中类型对应一个保存这种类型配件的vector
    vector<pii>vec[1001]; //保存每种类型的配件
    int b,n,cnt;
    bool check(int q)
    {
        vector<pii>::iterator it;
        int sum=0;
        for(int i=0;i<cnt;i++){
            it=lower_bound(vec[i].begin(),vec[i].end(),pii(q,0));
            if(it==vec[i].end())return 0;
            int minn=1e9;
            for(;it!=vec[i].end();it++)
                if(it->second<minn)minn=it->second;
            sum+=minn;
        }
        if(sum<=b)return 1;
        return 0;
    }
    int main()
    {
       //freopen("f.txt","r",stdin);
        int T;scanf("%d",&T);
        while(T--){
            for(int i=0;i<cnt;i++)vec[i].clear();
            mp.clear();
            cnt=0;
            vector<int>a;//保存出现过的品质因子
            map<int,bool>ma;  //判重,出现过的品质因子就不要再加到a中了
            scanf("%d%d",&n,&b);
            string s1,s2; int p,q;
            for(int i=0;i<n;i++){
                cin>>s1>>s2;
                scanf("%d%d",&p,&q);
                if(mp.count(s1)){
                    vec[mp[s1]].pb(mpi(q,p));
                }
                else{
                    mp[s1]=cnt++;
                    vec[mp[s1]].pb(mpi(q,p));
                }
                if(!ma.count(q))a.pb(q),ma[q]=1;
            }
            for(int i=0;i<cnt;i++)sort(vec[i].begin(),vec[i].end());
            int l=0,r=a.size()-1;
            sort(a.begin(),a.end());
            while(l<r){
                int m=(l+r)>>1;
                if(check(a[m]))l=m+1;
                else r=m-1;
            }
            if(l<a.size()&&check(a[l])) //因为二分,不确定是不是l是最优解,有可能l不是。所以再判断一下
                printf("%d
    ",a[l]);
            else if(check(a[l-1]))
                printf("%d
    ",a[l-1]);
        }
        return 0;
    }
  • 相关阅读:
    CentOS7 下更改源
    /usr/bin/perl:bad interpreter:No such file or directory 的解决办法
    Centos7 安装wget命令
    Cannot find a valid baseurl for repo: base/7/x86_6 解决方法
    python 启动新进程执行脚本
    MongoDB数据类型
    pymongo.errors.OperationFailure: Authentication failed.
    python连接MongoDB(有密码有认证)
    Mongodb 创建管理员帐号与普通帐号
    python连接MongoDB(无密码无认证)
  • 原文地址:https://www.cnblogs.com/01world/p/5651239.html
Copyright © 2020-2023  润新知