题意:某人想组装电脑,有很多电脑配件可以选,每样都有它的价格和质量,每种配件一定要买一个,现在给出钱数,求能组装出来的电脑里面配件质量最便宜的是多少。当然不能超出预算的啦。
每次枚举那个最便宜的,然后贪心,每次找价格最小且价格大于最便宜的,如果超支就向前二分,否则向后二分。
这题折腾了一晚上 = =,差点跪了。。。最后发现排序没处理好,郁闷。。。得先排前再排质量。
代码:
/* * 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; }