题目

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。

 

代码

Uva 12124 Uva Live 3971 - Assemble 二分, 判断器, g++不用map.size() 难度:0_#ifdefUva 12124 Uva Live 3971 - Assemble 二分, 判断器, g++不用map.size() 难度:0_#ifdef_02
#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;
}
View Code