uvalive 3971 - Assemble(二分搜索 + 贪心)

题目大意:有若干个零件, 每个零件给出的信息有种类, 名称, 价格, 质量,  现在给出一个金额, 要求在这个金额范围内, 将每个种类零件都买一个, 并且尽量让这些零件中质量最小的越大, 输出质量最小的值。


解题思路:首先可以用二分搜索确定质量, 然后在搜索的过程中要判断这个质量是否能被满足, 判断函数可以用贪心, 在每一类的零件中选择价格最低且质量大于等于当前质量的零件。(事先按照价格大小排序)。


#include <cstdio>
#include <string>
#include <vector>
#include <map>
using namespace std;

struct Component {
	int price;
	int quality;
};
vector<Component> comp[1005];

int cnt;
map<string, int> id;
int ID(string s) {
	if (!id.count(s)) 
		id[s] = cnt++;
	return id[s];
}

int n, b;
bool judge(int 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((Component) {p, q});
		}
		
		int L = 0, R = maxq;
		while (L < R) {
			int M = L + (R - L + 1) / 2;
			if (judge(M))
				L = M;
			else R = M - 1;
		}
		printf("%d\n", L);
	}
	return 0;
}

你可能感兴趣的:(uvalive 3971 - Assemble(二分搜索 + 贪心))