给你b块钱去组装一台电脑。
给出n个配件各自的种类、品质因子和价格,要求每个类型配件各买一个,总价格不超过b,且“品质最差配件”的品质因子尽量大。(即最小的品质因子尽量大)
分析:
1.解决“最小值最大”的问题常用方法是二分答案。
假设答案是x,如何判断x是最小还是最大呢?删除品质因子小于x的所有配件,如果可以组装出一台不超过b元的电脑,那么ans>=x,否则ans < x。
2.判断是否可以组装出满足预算约束的电脑:每一类配件选择最便宜的一个即可(删除小于x之后的)。如果这样都>b的话,就不可能有解了。
#include<cstdio>
#include<string>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
int cnt; //组件类型数
map<string, int> id; //存放每个类型的数量
int ID(string s)
{
if (!id.count(s))
id[s] = cnt++;
return id[s];
}
const int maxn = 1000 + 5;
struct Component
{
int price;
int quality;
};
int n, b;
vector<Component> comp[maxn]; //每个类型用一个vector存储
bool ok(int q) //品质因子不小于q的组件能否组装成一个电脑
{
int sum = 0;
for (int i = 0; i < cnt; i++)
{
int cheapest = b + 1, m = comp[i].size();
for (int j = 0; j < m; j++)
{
if (comp[i][j].quality >= q)
cheapest = min(cheapest, comp[i][j].price);
}
if (cheapest == b + 1)
return false;
sum += cheapest;
if (sum > b)
return false;
}
return true;
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
scanf("%d%d", &n, &b);
cnt = 0;
for (int i = 0; i < n; i++)
comp[i].clear();
id.clear();
int maxq = 0;
for (int i = 0; i < n; i++)
{
char type[30], name[30];
int p, q;
scanf("%s%s%d%d", type, name, &p, &q);
maxq = max(maxq, q);
comp[ID(type)].push_back({ p, q });
}
int L = 0, R = maxq;
while (L < R)
{
int M = L + (R - L + 1) / 2;
if (ok(M))
L = M;
else
R = M - 1;
}
printf("%d\n", L);
}
return 0;
}