南邮 OJ 1033 硬件DIY秀

硬件DIY秀

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 229            测试通过 : 34 

比赛描述

近期,计算机学院举办第四届学生课外科技节活动,硬件DIY秀活动使同学们组装电脑提高动手能力,主办方计算机学院分团委和科协决定购买电脑组件,每种类型的组件各需购买一个,并希望组装后的电脑能够实际使用。你的任务是帮助主办方最终确定购买何种性能组件,在最大限度地提高最低组件的性能,同时不能超过他们的预算。这里假设电脑的性能等同于其最薄弱组件的性能。



输入

第一行是一个正整数:测试用例数目,最多为100。之后,每个测试用例包括:

l         一行,含两个整数nb:1≤n≤1000,表示组件的数目,1≤b≤1000000000,表示他们的预算。

l         n行,按以下格式:“type name price quality”,type是一个字符串,表示组件的类型;name是一个字符串,表示组件的名称;price是一个整数(0≤price≤1000 000),表示组件的价格;quality是一个整数(0≤quality≤1000000000),表示组件的性能(越高越好)。字符串只能由字母和数字组成,最大长度为20个字符。

通常能够根据他们的预算来组装一台电脑。

输出

对于每个测试用例,输出包括:

l         一行,为一个整数:表示可能的最高性能。

样例输入

1
18 800
processor 3500_MHz 66 5
processor 4200_MHz 103 7
processor 5000_MHz 156 9
processor 6000_MHz 219 12
memory 1_GB 35 3
memory 2_GB 88 6
memory 4_GB 170 12
mainbord all_onboard 52 10
harddisk 250_GB 54 10
harddisk 500_FB 99 12
casing midi 36 10
monitor 17_inch 157 5
monitor 19_inch 175 7
monitor 20_inch 210 9
monitor 22_inch 293 12
mouse cordless_optical 18 12
mouse microsoft 30 9
keyboard office 4 10

样例输出

9

题目来源

南京邮电大学计算机学院首届ACM程序设计大赛(2009)



#include<iostream>
#include<algorithm>
#include<set>
#include<cstring>
using namespace std;

struct node1
{
	char s[25];
	long pri,qua;
	int kind;
}a[1010];

struct comp1{					//比较累,按照质量升序排序,质量相同的话按照价格降序排序
	bool operator()(const node1 &x,const node1 &y) const{
		if(x.qua==y.qua){
			return x.pri>y.pri;
		}
		return x.qua<y.qua;
	}
};

bool comp(const node1 &x,const node1 &y){
	if(!strcmp(x.s,y.s)){
		return x.pri<y.pri;			//名字相同,价格低的排在前面
	}else{
		return strcmp(x.s,y.s)<0;	//字典序
	}
}

int main(){
	freopen("test.txt","r",stdin);
	int c,n,b;
	scanf("%d",&c);
	while(c--){
		scanf("%d%d",&n,&b);
		getchar();
		int i;
		for(i=0;i<n;i++){
			scanf("%s%*s%d%d",&a[i].s,&a[i].pri,&a[i].qua);
		}
		sort(a,a+n,comp);			//按照种类名称排序,名称相同的话,按照价格从低到高排序

		i=0;
		int num=-1;
		int beg[1010],end[1010];
		while(i<n){					//给每个组件加上种类编号
			num++;					//种类从0开始编号
			beg[num]=i;				//beg[num]:种类编号为num的 最小ID
			a[i].kind=num;
			while(!strcmp(a[i].s,a[i+1].s))
			{
				i++;
				a[i].kind=num;
			}
			i++;
			end[num]=i;				//beg[num]:种类编号为num的 最大ID+1
		}
		a[n].kind=-1;
		multiset<node1,comp1>s;		// ?
		s.clear();
		num++;						//共有num个编号, 0……n-1
		int b_temp=0;
		for(i=0;i<num;i++){
			s.insert(a[beg[i]]);	// s 中存放每种编号的 最小ID 的节点
			b_temp+=a[beg[i]].pri;	// b_temp 每种组件的最低价的和
			beg[i]++;				// z最小标号考虑完之后就不在考虑
		}
		int ans;
		while(1)
		{
			int x=(*s.begin()).kind;//set中质量最低的种类编号
			ans=(*s.begin()).qua;	//set中质量最低的种类的 质量
			while((beg[x]<end[x])&&((*s.begin()).qua>=a[beg[x]].qua)){
				beg[x]++;			//找到同种类中质量稍微好一点的一个
			}
			if(beg[x]==end[x]){		//没有更好的质量了,就不找了,整体最优就是ans了
				break;
			}
			
			b_temp-=(*s.begin()).pri;
			s.erase(s.begin());
			
			b_temp+=a[beg[x]].pri;	//替换成更高质量的
			if(b_temp>b) break;		//花费超支的话就不谈了
			
			node1 temp;
			temp.kind=x;
			temp.pri=a[beg[x]].pri;
			temp.qua=a[beg[x]].qua;
			s.insert(temp);
			beg[x]++;
		}
		printf("%d\n",ans);
	}
	return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值