Assemble UVA - 12124 二分法

孤街浪徒 提交于 2020-03-01 01:24:22

问题

https://vjudge.net/problem/UVA-12124

分析

最小值最大,在保证总的花费少于b的情况下,使得质量的最小值最大。
使用二分法,对于质量进行二分法,每次取不同的质量x,计算最少的花费能否少于b,若少于,则尝试增加x,否则,减小x

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
using namespace std;
typedef long long LL;
const int maxn=1005,Inf=0x3f3f3f3f;
int T,n,b,qua,price,cnt;
string s1,s2;
map<string,int> str2id;
vector<string> id2str;

struct Comp{
    int p,q;
    Comp(int p=0,int q=0):p(p),q(q){}
};
vector<Comp> comp[maxn];

inline int ID(string &s){
    if(str2id.count(s)) return str2id[s];
    id2str.push_back(s);
    return str2id[s]=id2str.size()-1;
}

bool check(int x){
    int tot=0;
    bool flag=true;
    for(int i=0;i<cnt;++i) {
        int low = -1, lowp = Inf;
        for (int j = 0; j < comp[i].size(); ++j){
            if (comp[i][j].q >= x && comp[i][j].p < lowp) {
                lowp = comp[i][j].p;
                low = j;
            }
        }
        if(low==-1){
            flag=false;
        }else tot+=lowp;
        if(!flag || tot>b) return false;
    }
    return true;
}

int main(void){
    scanf("%d",&T);
    while(T--){
        str2id.clear();
        id2str.clear();
        scanf("%d%d",&n,&b);
        for(int i=0;i<=n;++i) comp[i].clear();
        int left=0,right=0;
        for(int i=0;i<n;++i){
            cin>>s1>>s2;
            scanf("%d%d",&price,&qua);
            comp[ID(s1)].push_back(Comp(price,qua));
            right=max(right,qua);
        }
        cnt=str2id.size();
        while(left<right){
            int mid=(left+right+1)/2;
            if(check(mid)) left=mid;
            else right=mid-1;
        }
        printf("%d\n",left);
    }
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!