• 组装电脑 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;
    }
  • 相关阅读:
    IIS7最大上传附件大小配置
    数据表的identity
    服务器×××上的MSDTC不可用解决办法——Orchard(转)
    IOS项目中使用全局变量
    九宫格解锁的实现
    UINavigationControlle类详解
    jar仓库
    django安装
    django入门
    值得阅读的pyhon文章
  • 原文地址:https://www.cnblogs.com/01world/p/5651239.html
Copyright © 2020-2023  润新知