前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >POJ 2797 金银岛(背包问题)

POJ 2797 金银岛(背包问题)

作者头像
天道Vax的时间宝藏
发布2021-08-11 10:39:26
3830
发布2021-08-11 10:39:26
举报
文章被收录于专栏:用户5305560的专栏

题目:金银岛

题意:

某天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位。

样例输入

代码语言:javascript
复制
2
50
4
10 100 50 30 7 34 87 100
10000
5
1 43 43 323 35 45 43 54 87 43

样例输出

代码语言:javascript
复制
171.93
508.00

题目理解:

需要定义一个金属块的结构体,结构体内存放金属块的重量,价值和单位重量的价值。输入数据后,调用sort排序对金属块按照其单位重量的价值进行从大到小排序,后按照排序后的金属块,利用for循环对背包当前所剩容量进行判断,若所剩容量大于等于当前金属快的质量,则将金属块全部放入背包;若小于,则将金属块切割后放入背包。当背包容量<=0的时候,则退出循环,则当前的背包所载金属块的价值最大。

注意:

  • 金属块质量和价值未必是整数,若定义int整形,可能会报错。
  • 金属块单位重量均值由价值v/质量w得到。
  • 注意保留小数位数为2。

代码:

代码语言:javascript
复制
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<deque>
#include<fstream>
#include<iomanip>
#include<map>
#include<queue>
#include<string>
#include<set>
#include<stack>
#include<vector>
typedef long long ll;
using namespace std;
struct js{  //定义金属块
	double w;
	double v;
	double avg;
}jsk[107];

bool cmp(struct js a,struct js b)
{
	return (a.avg>b.avg);
}

int main()
{
	int k;
	cin>>k;
	for(int s=0;s<k;s++)
	{
		int N;
		int S;
		cin>>S>>N;
		
		for(int i=0;i<N;i++)
		{
			cin>>jsk[i].w;
			cin>>jsk[i].v;
			jsk[i].avg=(1.0)*jsk[i].v/jsk[i].w;//求金属块每单位质量的价值
		}
		
	/*	for(int i=1;i<=N;i++)
		{
			cout<<jsk[i].w<<jsk[i].v<<endl;
			
		}*/
		
		sort(jsk,jsk+N,cmp);//按照均重从大到小排序
		

		/*for(int i=0;i<N;i++)
		{
		    cout<<jsk[i].avg<<endl;
		}*/
		
		double mm=0;
		for(int i=0;i<N;i++)
		{
			if(S<=0) break;//背包容量小于等于0,则表示背包全部装满,退出循环。
			if(jsk[i].w>S) {//如果当前金属块质量大于背包所剩载重,则将金属块进行切割。
				mm+=S*jsk[i].avg;
				S=0;
				
			}
			else {//如果当前金属块质量小于或等于所剩载重,则将金属块全部放入背包。
				mm+=jsk[i].v;
				S-=jsk[i].w;
			}
		}
		
		printf("%.2f\n",mm);
	}
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/08/03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目:金银岛
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档