ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

信息学奥赛一本通(1225:金银岛)

2021-06-27 18:29:53  阅读:424  来源: 互联网

标签:信息学 1225 背包 金属 性价比 gds 奥赛 物品 拿走


1225:金银岛


时间限制: 1000 ms         内存限制: 65536 KB
提交数: 8123     通过数: 4334

【题目描述】

某天KID利用飞行器飞到了一个金银岛上,上面有许多珍贵的金属,KID虽然更喜欢各种宝石的艺术品,可是也不拒绝这样珍贵的金属。但是他只带着一个口袋,口袋至多只能装重量为w的物品。岛上金属有s个种类, 每种金属重量不同,分别为n1,n2,...,ns,同时每个种类的金属总的价值也不同,分别为v1,v2,...,vs。KID想一次带走价值尽可能多的金属,问他最多能带走价值多少的金属。注意到金属是可以被任意分割的,并且金属的价值和其重量成正比。

【输入】

第1行是测试数据的组数k,后面跟着k组输入。

每组测试数据占3行,第1行是一个正整数w(1≤w≤10000),表示口袋承重上限。第2行是一个正整数s(1≤s≤100),表示金属种类。第3行有2s个正整数,分别为n1,v1,n2,v2,...,ns,vs分别为第一种,第二种,...,第s种金属的总重量和总价值(1≤ni≤10000,1≤vi≤10000)。

【输出】

k行,每行输出对应一个输入。输出应精确到小数点后2位。

【输入样例】

2
50
4
10 100 50 30 7 34 87 100
10000
5
1 43 43 323 35 45 43 54 87 43

【输出样例】

171.93
508.00

【分析】

        给定一个载重为M的背包,及n个重量为wi、价值为pi 的物体,要求把物品装满背包,且使背包内的物体价值最大,这类问题称为背包问题。有两类背包问题,即物体可以分割的背包问题,及物体不可分割的背包问题,我们把后者称为0/1背包问题,由0/1背包还可以延伸出很多背包问题。前者为可分割的背包问题,可以用贪心算法求解。贪心的策略是拿性价比高的物体。这一点也好理解,我们去超市免费拿东西,你挑最贵的拿,拿走一台冰箱,显然是傻蛋。如果物品可以分割,你当然应该去拿性价比高的物品,冰箱固然贵重,但其性价比并不贵,你应该直接奔金银首饰专柜去拿,金项链、翡翠这些都是性价比高的东西。

        以样例为例,我们来看求解过程。步骤为三步,分别是:

(1)求性价比

(2)按性价比,从大到小排序

(3)拿走最大价值

        从前到后物品开始拿,拿的策略是先拿性价比高的。如果当前背包重量 > 某个物品的总重量,那别客气,全拿走;否则,当前背包不足以拿走某个物品,那就能拿多少拿多少。样例数据,第一组,背包承重50,则先把第一个物品(性价比为10的)全拿走,价值=100,背包重量=40。同理,再把第二个物品全拿走,价值=134,背包重量=33,拿第三个,不足以全拿走,只能拿33,价值=134+33*1.15=171.93

【参考代码】

#include<stdio.h>
#include<string.h>
#define N 110
struct goods
{
	int n;     //总重量 
	double v;  //总价值 
	double p;  //性价比 
}gds[N],tmp;

int main()
{
	int t,i,j;
	int w;           //口袋承重上限 
	int s;           //金属种类 
	double sum=0;    //最多带走的价值 
	scanf("%d",&t);
	while(t--)
	{
		sum=0;
		memset(gds,0,sizeof(gds));

		scanf("%d%d",&w,&s);
		for(i=0;i<s;i++)
		{ 
			scanf("%d%lf",&gds[i].n,&gds[i].v);
			gds[i].p = gds[i].v / gds[i].n;
		}

		for(i=0;i<s-1;i++)      // 贪心策略是选性价比大的,按照性价比排序
		{
			for(j=i+1;j<s;j++)
		    {
		    	if(gds[i].p<gds[j].p)
				{
					tmp=gds[i];
					gds[i]=gds[j];
					gds[j]=tmp;
				}
			}
		}
		for(i=0;i<s;i++)       //枚举每件物品
		{
			if(w>gds[i].n)        //背包承重大于某物品的总重量,全拿走 
			{
				sum+=gds[i].v;
				w-=gds[i].n;
			}
			else                //背包承重小于某物品的总重量,切割物品,能拿多少拿多少 
			{
				sum+=gds[i].p*w;
				w=0;
			}
		}
		printf("%.2lf\n",sum);
	}
	return 0;
}

http://ybt.ssoier.cn:8088/problem_show.php?pid=1225

标签:信息学,1225,背包,金属,性价比,gds,奥赛,物品,拿走
来源: https://blog.csdn.net/lvcheng0309/article/details/118271838

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有