二分加贪心求最小值最大。
以下代码UVa用时49ms,HDU390ms,但在POJ就TLE了。
而且这个题实在让人费解,主要有两个疑惑:
1.使用lower_bound超时,遍历整个却不超时了。
2.mid用(lb + ub) / 2就会wa,必须要用mid = lb + (ub - lb + 1) / 2;
实在是难以理解….
我真是太菜了….
更新:
疑惑1:不能用lower_bound,因为有可能quality大的价格便宜,超时依旧不能理解。
#include <cstdio>
#include <cstring>
#include <map>
#include <string>
#include <set>
#include <algorithm>
using namespace std;
typedef pair<int, int> P;
map<string, set<P> > m;
bool ok1, ok2;
void check(int mid, int b) {
int budget = 0;
map<string, set<P> >::iterator itm;
ok1 = true;
for (itm = m.begin(); itm != m.end(); itm++) {
set<P> s = itm->second;
// set<P>::iterator its = s.lower_bound(P(mid, 0));
// if (its != s.end()) {
// budget += its->second;
// } else {
// ok1 = false;
// return;
// }
set<P>::iterator its;
int cheap = b + 1;
for (its = s.begin(); its != s.end(); its++) {
if (its->first >= mid) {
cheap = min(cheap, its->second);
}
}
if (cheap == b + 1) {
ok1 = false;
return;
}
budget += cheap;
}
ok2 = (budget <= b ? true : false);
}
int main(int argc, char const *argv[]) {
int t;
scanf("%d", &t);
while (t--) {
m.clear();
int n, b;
scanf("%d%d", &n, &b);
int inf = 0;
for (int i = 0; i < n; i++) {
getchar();
int price, quality;
char type[30], name[30];
memset(type, '\0', sizeof(type));
scanf("%s%s%d%d", type, name, &price, &quality);
m[type].insert(P(quality, price));
if (quality > inf) {
inf = quality;
}
}
int lb = 0, ub = inf;
while (lb < ub) {
// int mid = (lb + ub) / 2;
int mid = lb + (ub - lb + 1) / 2;
check(mid, b);
if (ok1 && ok2) {
lb = mid;
} else {
ub = mid - 1;
}
}
printf("%d\n", lb);
}
return 0;
}