携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情
P2240 【深基12.例1】部分背包问题
题目描述
阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有 堆金币,第 堆金币的总重量和总价值分别是 。阿里巴巴有一个承重量为 的背包,但并不一定有办法将全部的金币都装进去。他想装走尽可能多价值的金币。所有金币都可以随意分割,分割完的金币重量价值比(也就是单位价格)不变。请问阿里巴巴最多可以拿走多少价值的金币?
输入格式
第一行两个整数 。
接下来 行,每行两个整数 。
输出格式
一个实数表示答案,输出两位小数
样例 #1
样例输入 #1
4 50
10 60
20 100
30 120
15 45
样例输出 #1
240.00
思路
题目说是背包问题,其实和背包问题关系不大
做法就是贪心
对于每一堆金币创建一个结构体,内部存放着金币的个数和重量
对于金币重量比对结构体数组进行排序
然后从前往后尽可能多的拿取金币即可
代码
// P2240 【深基12.例1】部分背包问题
// 贪心+结构体排序
#include <bits/stdc++.h>
using namespace std;
struct gold
{
int w;
float v;
}gg[110];
bool cmp(gold a, gold b){
//回调函数
return (a.v/a.w) > (b.v/b.w);
}
int main(int argc, char const *argv[])
{
float ret = 0;
float nowt,t;
int n;
cin >> n >> t;
nowt = t;
//读取数据
for(int i=0; i<n; i++){
cin >> gg[i].w >> gg[i].v;
}
sort(gg, gg+n, cmp);
for(int i=0; i<n; i++){
if(gg[i].w <= nowt){
ret += gg[i].v;
nowt -= gg[i].w;
} else if(gg[i].w > nowt){
ret += nowt*gg[i].v/gg[i].w;
break;
}
}
printf("%.2f",ret);
return 0;
}