Uva 12124 Assemble

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3276

题目大意:有b块的预算,要组装一台电脑,给出n个配件,每个配件标明种类,名称,品质和价格,要求每种配件各买一个,从价格不超过b,且品质最低的配件的品质尽可能大。输出最小品质配件的品质。


解题关键:“最小值最大”问题常用方法是二分法,对所有配件的品质进行二分。假设二分得到的值为x,在每种配件中选择品质大于等于x的最便宜配件,若最后花费<b则ans>=x,否则ans<x.


import java.util.*;

class Component
{
	String name;
	int price;
	int quality;
	public Component(String name,int price,int quality)
	{
		this.name=name;
		this.price=price;
		this.quality=quality;
	}
}

public class Main {

	static int n,b;
	static int count;
	static Map<String,Integer> kind_num=new HashMap<String,Integer>();
	static ArrayList<ArrayList<Component>> comp=null;
	static int ID(String type)
	{
		int res=0;
		if(kind_num.containsKey(type))
		{
			res=kind_num.get(type);
		}
		else
		{
			kind_num.put(type, count);
			res=count;
			count++;
		}
		return res;
	}
	static int min(int a,int b)
	{
		return a<b?a:b;
	}
	static boolean OK(int M)
	{
		int sum=0;
		for(int i=0;i<count;i++)
		{
			ArrayList<Component> temp=comp.get(i);
			int cheapest=b+1;
			for(int j=0;j<temp.size();j++)
			{
				if(temp.get(j).quality>=M) cheapest=min(cheapest,temp.get(j).price);
			}
			if(cheapest==b+1) return false;
			sum=sum+cheapest;
			if(sum>b) return false;
		}
		return true;
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int t;
		Scanner in=new Scanner(System.in);
		t=in.nextInt();
		for(;t>0;t--)
		{
			kind_num.clear();
			n=in.nextInt();
			b=in.nextInt();
			comp=new ArrayList<ArrayList<Component>>();
			for(int i=0;i<n;i++)
			{
				ArrayList<Component> tem=new ArrayList<Component>();
				comp.add(tem);
			}
			int type_num=0;
			count=0;
			int max=Integer.MIN_VALUE,min=Integer.MAX_VALUE;
			for(int i=0;i<n;i++)
			{
				String type=in.next();
				String name=in.next();
				int price=in.nextInt();
				int quality=in.nextInt();
				if(quality>=max)
					max=quality;
				if(quality<min)
					min=quality;
				int num=ID(type);
				Component temp=new Component(name,price,quality);
				comp.get(num).add(temp);
			}
			int L=min,R=max;
			while(L<R)
			{
				int M=L+(R-L+1)/2;
				if(OK(M))
				{
					L=M;
				}
				else
				{
					R=M-1;
				}
			}
			System.out.println(L);
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值