题目描述
阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有 N(N \le 100)N(N≤100) 堆金币,第 ii 堆金币的总重量和总价值分别是 m_i,v_i(1\le m_i,v_i \le 100)mi,vi(1≤mi,vi≤100)。阿里巴巴有一个承重量为 T(T \le 1000)T(T≤1000) 的背包,但并没办法将全部的金币都装进去。他想装走尽可能多价值的金币。所有金币都可以随意分割,分割完的金币重量价值比(也就是单位价格)不变。请问阿里巴巴最多可以拿走多少价值的金币?
输入格式
第一行两个整数 N、T
接下来 N 行,每行两个整数 m_i,v_imi,vi
输出格式
一个整数表示答案,输出两位小数
输入输出样例
输入 #1复制
4 50 10 60 20 100 30 120 15 45
输出 #1复制
240.00
【思路】
因为金币可以任意分割,我们不用担心因为背包的体积, 放入一个背包后, 无法放入其他背包。
步骤如下, 我们根据每组背包的总价值和体积,计算出每组背包的单位价格。并按照单位价格排序。
然后优先放入单位价值高的金币。直到背包容量为空为止。(因为背包可以分割,所以,如果背包剩余空间放不下一组的话,可以把这一组的金币分开存放。)
【代码】
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Good {
int w, v;
double p;
bool operator<(const Good & a) const {
return p > a.p;
}
};
const int N = 105;
Good a[N];
int n, t;
double res;
int main() {
cin >> n >> t;
for(int i = 0 ;i < n; i++) {
scanf("%d%d", &a[i].w, &a[i].v);
a[i].p = double(a[i].v) / a[i].w;
}
sort(a, a + n);
for(int i = 0 ;i < n; i++) {
if(t > a[i].w) {
res += a[i].v;
t -= a[i].w;
} else {
res += t * a[i].p;
break;
}
}
printf("%.2lf", res);
return 0;
}
洛谷P2240:部分背包问题解析与解决方案

阿里巴巴面临一个部分背包问题,需要在承重量限制下最大化装走金币的总价值。每堆金币可任意分割,保持单位价格不变。问题通过计算每堆金币的单位价值并按降序排列,优先选取单位价值高的金币装入背包来解决。给出的代码实现了这一策略。
1545

被折叠的 条评论
为什么被折叠?



