B3.圣诞老人的礼物

【题目描述】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;
}

运行结果

可见我们实现了该问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值