POJ 2797 金银岛(背包问题)

2021-08-11 10:39:26 浏览数 (1)

题目:金银岛

题意:

某天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("%.2fn",mm);
	}
	return 0;
}

0 人点赞