题意:某人想组装电脑,有很多电脑配件可以选,每样都有它的价格和质量,每种配件一定要买一个,现在给出钱数,求能组装出来的电脑里面配件质量最便宜的是多少。当然不能超出预算的啦。
每次枚举那个最便宜的,然后贪心,每次找价格最小且价格大于最便宜的,如果超支就向前二分,否则向后二分。
这题折腾了一晚上 = =,差点跪了。。。最后发现排序没处理好,郁闷。。。得先排前再排质量。
代码:
/*
* Author: illuz <iilluzen[at]gmail.com>
* Blog: http://blog.csdn.net/hcbbt
* File: l3971.cpp
* Create Date: 2013-09-09 21:14:09
* Descripton: binary, greedy
*/
#include <cstdio>
#include <vector>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
const int MAXN = 1000;
struct P {
string nam;
int mon;
int qua;
friend bool operator < (const P &a, const P &b) {
if (a.mon != b.mon)
return a.mon < b.mon;
return a.qua > b.qua;
}
P() {}
P(string s, int m, int q) {
nam = s;
mon = m;
qua = q;
}
};
int n, b, cnt;
set<P> v[MAXN];
map<string, int> app;
bool judge(int m) {
int sum = 0;
for (int i = 1; i < cnt; i++) {
bool choose = false;
for (set<P>::iterator j = v[i].begin(); j != v[i].end(); j++) {
if ((*j).qua >= m) {
// cout << sum << ' ';
choose = true;
sum += (*j).mon;
break;
}
}
if (false == choose || sum > b)
return false;
}
return true;
}
int main() {
int t;
string tmp;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &b);
int tm, tq;
int L = 0, R = 0, mid;
app.clear();
for (int i = 1; i < cnt; i++)
v[i].clear();
cnt = 1;
for (int i = 0; i < n; i++) {
cin >> tmp;
scanf("%*s%d%d", &tm, &tq);
R = max(R, tq);
if (app[tmp] == 0) {
app[tmp] = cnt;
v[cnt++].insert(P(tmp, tm, tq));
}
else
v[app[tmp]].insert(P(tmp, tm, tq));
}
while (L < R) {
mid = L + (R - L) / 2;
if (L == mid) break;
if (judge(mid)) L = mid;
else R = mid;
// cout << "\n!!!!!!!!!!!!" << mid << endl;
}
if (judge(mid + 1)) mid++;
printf("%d\n", mid);
}
return 0;
}