HDU-Fish买电脑 二分查找
这题可以用二分枚举答案来求解,每次枚举一个答案时我们总是选取满足要求的每个零件的价格最小者,如果金钱能够满足的话就枚举一个更大的质量,这里最好将质量离散化,这样就能枚举每个点都用相应的品质对应。
代码如下:
#include <cstring> #include <cstdio> #include <cstdlib> #include <algorithm> #include <map> using namespace std; map<int,int>mp; int fee[1005]; struct Node { char name[25], type[25]; int p, q; bool operator < (Node temp) const { return strcmp(name, temp.name) < 0; } }e[1005]; struct Point { int no, x; bool operator < (Point temp) const { return x < temp.x; } bool operator == (Point temp) const { return x == temp.x; } }p[1005]; int N, M; bool Ac(int x) { int left = M, idx = -1; for (int i = 0; i <= 1000; ++i) { fee[i] = 1 << 30; } for (int i = 0; i < N; ++i) { if (i == 0) { ++idx; if (mp[e[i].q] >= x) { fee[idx] = min(fee[idx], e[i].p); } } else { if (strcmp(e[i].name, e[i-1].name) == 0) { if (mp[e[i].q] >= x) { fee[idx] = min(fee[idx], e[i].p); } } else { left -= fee[idx]; if (left < 0) { return false; } ++idx; if (mp[e[i].q] >= x) { fee[idx] = min(fee[idx], e[i].p); } } } } left -= fee[idx]; if (left < 0) { return false; } return true; } int bsearch(int l, int r) { int mid, ret = 0; while (l <= r) { mid = (l + r) >> 1; if (Ac(mid)) { ret = mid; l = mid + 1; } else { r = mid - 1; } } return ret; } int main() { int cnt, ret; int T; scanf("%d", &T); while (T--) { scanf("%d %d", &N, &M); mp.clear(); for (int i = 0; i < N; ++i) { scanf("%s %s %d %d", e[i].name, e[i].type, &e[i].p, &e[i].q); p[i].x = e[i].q; } sort(e, e + N); sort(p, p + N); cnt = unique(p, p + N) - p; for (int i = 0; i < cnt; ++i) { mp[p[i].x] = i; } ret = bsearch(0, cnt-1); printf("%d\n", p[ bsearch(0, cnt-1) ].x); } return 0; }