【题目描述】POJ4110
圣诞节来临了, 在城市 A 中圣诞老人准备分发糖果,现在有多箱不同的糖果:
• 每箱糖果有自己的价值和重量
• 每箱糖果都可以拆分成任意散装组合带走
• 圣诞老人的驯鹿最多只能承受一定重量的糖果
• 请问圣诞老人最多能带走 多大价值的糖果
【输入格式】
第一行由两个部分组成, 分别为 • 糖果箱数正整数 n (1 <= n <= 100)
驯鹿能承受的最大重量正整数 w (0 < w < 10000) 两个数用空格隔开
其余 n 行每行对应一箱糖果, 由两部分组成
一箱糖果的价值正整数 v
一箱糖果的重量正整数 w 中间用空格隔开
【输出格式】
输出圣诞老人能带走的糖果的最大总价值, 保留 1 位小数
输出为一行, 以换行符结束
【样例输入】
4 15 |
100 4 |
412 8 |
266 7 |
591 2 |
【样例输出】
1193.0 |
题目分析
简单来讲,这个题目就是给定一系列糖果,每个糖果有价值(value)和重量(weight),以及一个背包的最大承载重量(W),要求找出能够装入背包的糖果的最大总价值。
我们可以先定义一个结构体Candy来存储糖果信息,然后输入信息,分析题目后发现肯定需要排序,排完序后进行贪心选择,装入最有价值的糖果,然后输出即可。我们直接上代码:
实现代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
using namespace std;
// 定义Candy结构体,用于存储糖果的价值、重量和单位价值
struct Candy {
int value; // 糖果的价值
int weight; // 糖果的重量
double unitvalue; // 糖果的单位价值(价值/重量)
};
// 比较函数,按照单位价值从高到低排序糖果
bool compareCandies(const Candy& a, const Candy& b) {
return a.unitvalue > b.unitvalue;
}
int main() {
int n, W;
// 输入糖果箱数n和驯鹿能承受的最大重量W
cin >> n >> W;
// 创建一个Candy类型的向量,用于存储所有糖果的信息
vector<Candy> candies(n);
// 遍历输入,为每箱糖果赋值价值和重量,并计算单位价值
for (int i = 0; i < n; ++i) {
cin >> candies[i].value >> candies[i].weight;
// 计算并存储单位价值
candies[i].unitvalue = static_cast<double>(candies[i].value) / candies[i].weight;
}
// 使用sort函数和比较函数对糖果进行排序
sort(candies.begin(), candies.end(), compareCandies);
// 初始化总价值和当前重量为0
double totalValue = 0.0;
int currentWeight = 0;
// 遍历排序后的糖果列表,尝试将糖果装入背包
for (const auto& candy : candies) {
// 如果当前糖果可以完全装入背包
if (currentWeight + candy.weight <= W) {
// 更新总价值和当前重量
totalValue += candy.value;
currentWeight += candy.weight;
}
else if (currentWeight < W) {
// 如果当前糖果不能完全装入,但背包还有剩余空间
// 计算剩余空间
double remainingWeight = W - currentWeight;
// 按照剩余空间的比例装入糖果,并更新总价值
totalValue += candy.unitvalue * remainingWeight;
// 背包已满或无法再装入更多糖果,跳出循环
break;
}
}
// 输出最大总价值,保留一位小数
cout << fixed << setprecision(1) << totalValue << endl;
return 0;
}
运行结果
可见我们实现了该问题