现在的位置: 首页 > 综合 > 正文

HDU 2333 & POJ 3497 & UVA 12124 Assemble (二分答案)

2018年02月23日 ⁄ 综合 ⁄ 共 1415字 ⁄ 字号 评论关闭

题意:有b块钱,要装一台电脑,给出n个配件各自的种类、品质因子和贾哥,要求每种类型的配件各买一个,总价不超过b,且“品质最差配件”的品质因子应尽量大,输出最小品质因子的最大值。

思路:解决“最小值最大”的常用方法就是二分答案。假设答案为x,那么删除品质小于x的所有配件,如果能组装出一台电脑,那么正确答案ans>=x,否则ans<x。

如何判定能组装出一台电脑呢?只要在删除品质小于x的所有配件后,取每种配件最便宜的一件,把价格加起来不超过b就可以了。

#include<cstdio>
#include<string>
#include<map>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 1005
#define INF 0x3f3f3f3f
using namespace std;
map< string,int > id;
int T,n,b,cnt;
char tmp[30];
struct Obj {int price,quality,type;}obj[MAXN];
bool cmp(Obj a,Obj b) {return a.quality<b.quality;}
int insert(string s)
{
	if(!id[s]) id[s]=cnt++;
	return id[s];
}
bool check(int x)
{
	int sum=0,kind=0,cheapest[MAXN];
	memset(cheapest,INF,sizeof(cheapest));//记录每件配件的最小价值,初始化都是INF
	
	for(int i=1;i<=n;++i)
	{
		if(obj[i].quality<x) continue;//不考虑品质因子小于x的物品
		if(cheapest[obj[i].type]==INF) ++kind,sum+=obj[i].price,cheapest[obj[i].type]=obj[i].price;
		else if(obj[i].price<cheapest[obj[i].type]) sum=sum-cheapest[obj[i].type]+obj[i].price,cheapest[obj[i].type]=obj[i].price;
	}
	return sum<=b && kind==cnt-1;//如果总价不超过b,而且所选种数等于总种类数(也就是所有种类都选了一件),那么返回true,否则返回false
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&b);
		cnt=1; id.clear();
		int maxquality=0;
		for(int i=1;i<=n;++i)
		{
			scanf("%s",tmp);
			obj[i].type=insert(tmp);
			scanf("%s",tmp);
			scanf("%d %d",&obj[i].price,&obj[i].quality);
			maxquality=max(maxquality,obj[i].quality);
		}
		int low=0,high=maxquality;
		while(low<high)
		{
			int mid=low+(high-low+1)/2;
			if(check(mid)) low=mid;
			else high=mid-1;
		}
		printf("%d\n",low);
	}
	return 0;
}

抱歉!评论已关闭.