问题
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;
}
来源:CSDN
作者:carut
链接:https://blog.csdn.net/zpf1998/article/details/104580250