题目链接:UVA-LA 3971
题意:用不超过b的预算,购置电脑硬件,每种都需要购办一个,且要使品质最差的硬件的品质数最大。
题解:二分枚举,在每种硬件里都选择比不小于当前品质(记为k)高硬件,如果预算不超过b,那么ans >= k;如果超过b,ans < k;
AC code:
#include<cstdio>
#include<map>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
#define debug 0
const int maxn = 1000 + 5;
struct R{
int p;
int q;
};
vector<R> r[maxn];
map<string, int> id; //构造map
int n, v, cnt;
int ID(string s) { //用map将同种硬件的信息放在一个vector内
if (!id.count(s))
return id[s] = cnt++;
return id[s];
}
bool check(int k) {
int sum = 0;
for (int i = 1; i < cnt; i++) {
int mn = v + 1; //枚举当前品质
for (int j = 0; j < r[i].size(); j++) {
if (r[i][j].q >= k) {
mn = min(mn, r[i][j].p);
}
}
if (mn == v + 1)
return false;
sum += mn;
if (sum > v)
return false;
}
return true;
}
int main() {
#if debug
freopen("in.txt", "r", stdin);
#endif //debug
int t;
scanf("%d", &t);
char k[30], o[30];
int a, b;
while (t--) {
scanf("%d%d", &n, &v);
int mx = 0;
cnt = 1;
//printf("%d\n", mx);
for (int i = 1; i <= n; i++)
r[i].clear(); //vector容器清空 ,下面map也是一样的
for (int i = 1; i <= n; i++) {
scanf("%s%s%d%d", k, o, &a, &b);
mx = max(mx, b);
R temp;
temp.p = a;
temp.q = b;
r[ID(k)].push_back(temp);
}
//printf("%d\n", mx);
int l = 0, r = mx;
while (l < r) { //注意这里的mid,上层枚举的ans >= l所以要枚举的mid 一定要大于l不然可能会死循环
int mid = l + (r - l + 1) / 2;
if (check(mid)) {
l = mid;
}else{
r = mid - 1;
}
}
id.clear();
printf("%d\n", l);
}
return 0;
}