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;
    }
  • 相关阅读:
    Recommended Books for Algo Trading in 2020
    Market Making is simpler than you think!
    Top Crypto Market Makers of 2020
    Top Crypto Market Makers, Rated and Reviewed
    爬取伯乐在线文章(五)itemloader
    爬取伯乐在线文章(四)将爬取结果保存到MySQL
    爬取伯乐在线文章(三)爬取所有页面的文章
    爬取伯乐在线文章(二)通过xpath提取源文件中需要的内容
    爬取伯乐在线文章(一)
    爬虫去重策略
  • 原文地址:https://www.cnblogs.com/01world/p/5651239.html
Copyright © 2011-2022 走看看