题意:你有b元钱,想要组装一台电脑,给出n个配件的各自的种类、品质因子和价格,要求每种类型的派件各买一个,总价格不超过b,且“品质最差配件”的品质因子应该尽量大 (题目保证有解),输出配件最小品质因子的最大值

分析:既然题目保证有解,那么每种配件都选品质最差的是一个极端,每种都选品质最好有是一个极端,在两个极端之间二分就可以得到答案。

 1 #pragma warning(disable:4786)
 2 #include <stdio.h>
 3 #include <iostream>
 4 #include <string>
 5 #include <vector>
 6 #include <map>
 7 #define zzz
 8 using namespace std;
 9 int min(int a, int b){
10     return a<b?a:b;
11 }
12 int max(int a, int b){
13     return a>b?a:b;
14 }
15 const int MAXN = 1000 + 5;
16 int cnt;
17 map<string, int>id;
18 int ID(string s){
19     if(!id.count(s)) id[s]=cnt++;
20     return id[s];
21 }
22 struct ZZ{
23     int p, q;
24 };
25 vector<ZZ>zz[MAXN];
26 int b, n;
27 bool erfen(int q){
28     int sum = 0;
29     for(int i=0; i<cnt; i++){
30         int bargin = b + 1;
31         int m = zz[i].size();
32         for(int j=0; j<m; j++){
33             if(zz[i][j].q>=q) bargin = min(bargin, zz[i][j].p);
34         }
35         if(bargin == b+1) return false;
36         sum += bargin;
37         if(sum>b) return false;
38     }
39     return true;
40 }
41 int main(){
42 #ifndef zzz
43     freopen("in.txt", "r", stdin);
44 #endif
45     int cas;
46     scanf("%d", &cas);
47     while(cas--){
48         scanf("%d%d", &n, &b);
49         cnt = 0;
50         int i;
51         for(i=0; i<n; i++) zz[i].clear();
52         id.clear();
53         int maxq = 0;
54         for(i=0; i<n; i++){
55             char type[30], name[30];
56             int p, q;
57             scanf("%s%s%d%d", type, name, &p, &q);
58             maxq = max(maxq, q);
59             ZZ tmp;
60             tmp.p = p;
61             tmp.q = q;
62             zz[ID(type)].push_back(tmp);
63         }
64         int l = 0;
65         int r = maxq;
66         while(l<r){
67             int m = (l+r+1)/2;
68             if(erfen(m)) l = m;
69             else r = m - 1;
70         }
71         printf("%d\n", l);
72     }
73     return 0;
74 }

 

Greatness is never a given, it must be earned.