题目大意:
你有b块钱,想要组装一台电脑。给出n个配件各自的种类、品质因子和价格,要求每种类型的配件各买一个,总价格不超过b,且“品质最差配件”的品质因子应尽量大。
【输入格式】
输入的第一行为测试数据组数T(T≤100)。每组数据的第一行为两个正整数n(1≤
n≤1 000)和b(1≤b≤109),即配件的数目和预算;以下n行每行描述一个配件,依次为种类、名称、价格和品质因子。其中,价格为不超过106的非负整数;品质因子是不超过109的非负整数(越大越好);种类和名称则由不超过20个字母、数字和下划线组成。输入保证总是有解。
【输出格式】
对于每组数据,输出配件最小品质因子的最大值。
分析:
在《入门经典》一书中,我们曾提到过,解决“最小值最大”的常用方法是二分答案。假设答案为x,如何判断这个x是最小还是最大呢?删除品质因子小于x的所有配件,如果可以组装出一台不超过b元的电脑,那么标准答案ans≥x,否则ans<x。
如何判断是否可以组装出满足预算约束的电脑呢?很简单,每一类配件选择最便宜的一个即可。如果这样选都还超预算的话,就不可能有解了。
import java.util.*;
public class Main {
static int cnt ,n, b;
static HashMap<String,Integer> id = new HashMap<String,Integer>();
static ArrayList<ArrayList<Component>> comps = null;
static Integer ID(String s) {
int res=0;
if(id.containsKey(s)) {
res=id.get(s);
}else {
id.put(s, cnt);
res = cnt;
cnt++;
}
return res;
}
static void init() {
cnt = 0;
id.clear(); //初始化id
comps = new ArrayList<ArrayList<Component>>();
for(int i=0;i <= n;i++) {
ArrayList<Component> tmp =new ArrayList<Component>();
comps.add(tmp);
}
}
static boolean judge(int q) {
int sum = 0;
for(int i = 0; i < cnt; i++) {
int cheapest = b + 1;
for(int j = 0; j < comps.get(i).size(); j++) {
if(comps.get(i).get(j).quality >= q)
cheapest = Math.min(cheapest, comps.get(i).get(j).price);
}
if(cheapest == b + 1) {
return false;
}
sum += cheapest;
if(sum > b) {
return false;
}
}
return true;
}
public static void main(String []args) {
Scanner cin = new Scanner(System.in);
int T;
T = cin.nextInt();
while(T-- > 0) {
n = cin.nextInt();
b = cin.nextInt();
init();
int maxq = Integer.MIN_VALUE , minq = Integer.MAX_VALUE;
String type, name;
int p , q;
for(int i = 0; i < n; i++) {
type = cin.next();
name = cin.next();
p = cin.nextInt();
q = cin.nextInt();
maxq = Math.max(maxq,q);
minq = Math.min(minq,q);
int num = ID(type);
comps.get(num).add(new Component(p,q));
}
int left = minq , right = maxq;
while(left < right) {
int mid = left + (right - left + 1) / 2;
if(judge(mid)) {
left = mid;
}else {
right = mid - 1;
}
}
System.out.printf("%d\n", left);
}
}
}
class Component {
int price;
int quality;
Component(int p,int q) {
this.price = p;
this.quality = q;
}
}