题目
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1972
题意
给定预算,要求各种类配件一个,品质最小最大问题
思路
如刘书思路。
有一个O(n)时间判定答案是否正确的确定性or随机判断器 + 判断算法是现代算法,随机算法,量子加密的基础,必须要掌握的思路。
感想
1. Uva 很快过了,但是UvaLA怎么也不过,后来发现是 if(mp.count(key)==0)mp[key] = mp.size();这种姿势在g++中行不通。虽然不明白是为什么,但是g++总会有各种小bug。
代码
#include <algorithm> #include <cassert> #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <queue> #include <tuple> #include <set> #include <map> #include <cassert> #define LOCAL_DEBUG using namespace std; typedef pair<int, int> MyPair; const int MAXN = 1e3 + 3; MyPair items[MAXN][MAXN]; int itemsCnt[MAXN]; int leastPrices[MAXN][MAXN]; int budget; int kindsNum; bool check(int quaMn) { int remain = budget; for (int kind_ind = 0; kind_ind < kindsNum; kind_ind++) { int cnt = itemsCnt[kind_ind]; if (quaMn > items[kind_ind][cnt - 1].first)return false; int ind = lower_bound(items[kind_ind], items[kind_ind] + cnt, MyPair(quaMn, 0)) - items[kind_ind]; remain -= leastPrices[kind_ind][ind]; if (remain < 0)return false; } return true; } int search(int l, int r) { int mid = (l + r) >> 1; if (mid == l)return l; if (check(mid)) { return search(mid, r); } else { return search(l, mid); } } int main() { #ifdef LOCAL_DEBUG freopen("input.txt", "r", stdin); //freopen("output2.txt", "w", stdout); #endif // LOCAL_DEBUG int T; scanf("%d", &T); for (int ti = 1; ti <= T; ti++) { memset(itemsCnt, 0, sizeof(itemsCnt)); map<string, int> kinds_map; int n; scanf("%d%d", &n, &budget); kindsNum = 0; int min_qua = 1e9 + 9, max_qua = 0; for (int i = 0; i < n; i++) { char tmp[1024]; scanf("%s", tmp); if (kinds_map.count(tmp) == 0) { kinds_map[tmp] = kindsNum++; } int kind_ind = kinds_map[tmp]; scanf("%s", tmp); int price, qua; scanf("%d%d", &price, &qua); items[kind_ind][itemsCnt[kind_ind]++] = MyPair(qua, price); min_qua = min(min_qua, qua); max_qua = max(max_qua, qua); } for (int kind_ind = 0; kind_ind < kindsNum; kind_ind++) { int cnt = itemsCnt[kind_ind]; sort(items[kind_ind], items[kind_ind] + cnt); for (int j = 0; j < cnt; j++) { leastPrices[kind_ind][j] = items[kind_ind][j].second; } for (int j = 1; j < cnt; j++) { if (items[kind_ind][j].first == items[kind_ind][j - 1].second) { leastPrices[kind_ind][j] = leastPrices[kind_ind][j - 1]; } } for (int j = cnt - 2; j >= 0; j--) { leastPrices[kind_ind][j] = min(leastPrices[kind_ind][j + 1], leastPrices[kind_ind][j]); } } int ans = search(0, max_qua + 1); printf("%d\n", ans); } return 0; }