zoukankan      html  css  js  c++  java
  • 组装电脑 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;
    }
  • 相关阅读:
    LLC半桥谐振变换器调试记录
    工业派学习记录
    ubuntu 命令记录
    电容单位换算
    Windows快捷键
    CAN总线学习笔记
    Scala 基础(十五):Scala 模式匹配(三)
    Scala 基础(十四):Scala 模式匹配(二)
    Scala 基础(十三):Scala 模式匹配(一)
    scala 数据结构(十一):流 Stream、视图 View、线程安全的集合、并行集合
  • 原文地址:https://www.cnblogs.com/01world/p/5651239.html
Copyright © 2011-2022 走看看