圣诞老人的礼物

【题目描述】

圣诞节来临了, 在城市 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

【代码分析】

一、整体思路

这段代码旨在解决圣诞老人在驯鹿载重限制下,选择不同价值和重量的糖果箱,以获取最大总价值糖果的问题。其核心思路是通过比较每箱糖果的单位价值(价值除以重量),优先选择单位价值高的糖果箱,直到驯鹿达到最大承受重量。

二、数据结构定义

定义了结构体 Box,包含三个成员变量:

  • v:表示一箱糖果的价值。
  • w:表示一箱糖果的重量。
  • a:用于存储每箱糖果的单位价值(通过 v 除以 w 计算得出)。

三、函数 Gao

  • 这是一个比较函数,用于比较两个 Box 结构体对象的单位价值 a
  • 返回 a.a > b.a 的结果,目的是为了后续在排序或查找单位价值最高的糖果箱时使用,使得能够按照单位价值从高到低的顺序来处理糖果箱。

四、main 函数部分

  1. 输入部分

    • 首先读取两个整数 n 和 mw,分别表示糖果箱数和驯鹿能承受的最大重量。
    • 然后通过动态分配内存创建了一个 Box 结构体类型的数组 p,用于存储每箱糖果的信息。接着通过循环读取每箱糖果的价值 v 和重量 w,并计算出每箱糖果的单位价值 a,存储到数组 p 对应的元素中。
  2. 选择糖果箱过程

    • 定义了两个变量 sw(已选糖果的总重量)和 totalv(已选糖果的总价值),初始值都为 0。
    • 在 while 循环中,只要 sw(已选糖果总重量)小于 mw(驯鹿最大承受重量),就会进行以下操作:
      • 首先通过一个内层循环遍历数组 p,找到单位价值 a 最高的糖果箱,记录其单位价值 tempa 和对应的索引 tempb
      • 然后判断该糖果箱的重量 p[tempb].w 是否小于等于剩余可承载重量(mw - sw):
        • 如果是,说明可以直接选择整箱糖果,将该箱糖果的价值 p[tempb].v 加到 totalv 中,同时更新已选糖果的总重量 sw 为 sw + p[tempb].w,并将该箱糖果的单位价值 p[tempb].a 设置为 0,意味着这箱糖果已被完全选取。
        • 如果不是,说明不能选择整箱糖果,只能选取部分。此时根据剩余可承载重量(mw - sw)和该箱糖果的单位价值 p[tempb].a,计算出能选取部分糖果的价值((mw - sw) * p[tempb].a),加到 totalv 中,同时更新已选糖果的总重量 sw 为 sw + mw - sw(即达到最大承载重量),同样将该箱糖果的单位价值 p[tempb].a 设置为 0。
  3. 输出部分

    最后通过 printf 函数按照保留一位小数的要求输出 totalv,即圣诞老人能带走的糖果的最大总价值。

【代码实现】

using namespace std;
#include <iostream>

struct Box
{
	int v;		//价值
	int w;		//重量
	double a;	//平均
};

bool Gao(Box a, Box b)
{
	return a.a > b.a;
}

int main()
{
	int n, mw;
	cin >> n >> mw;		//输入箱数  最大承受重量
	Box* p;
	p = new Box[n];
	for (int i = 0; i < n; i++)		//数组存放每箱糖果
	{
		cin >> p[i].v >> p[i].w;
		p[i].a = double(p[i].v) / double(p[i].w);
	}
	int sw = 0;
	double totalv = 0;
	while (sw < mw)		//是否达到最大承受量
	{
		double tempa=0;
		int tempb;
		int i = 0;
		for (; i < n; i++)		//价值最大的箱子
		{
			if (p[i].a > tempa)
			{
				tempa = p[i].a;
				tempb = i;
			}
		}
		if (p[tempb].w <= mw - sw)		//是否需要拆分
		{
			totalv += p[tempb].v;
			sw += p[tempb].w;
			p[tempb].a = 0;
		}
		else
		{
			totalv += (mw - sw) * p[tempb].a;
			sw += mw - sw;
			p[tempb].a = 0;
		}
	}
	printf("%.1f\n", totalv);
	return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值