【题目描述】
圣诞节来临了, 在城市 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
函数部分
-
输入部分:
- 首先读取两个整数
n
和mw
,分别表示糖果箱数和驯鹿能承受的最大重量。 - 然后通过动态分配内存创建了一个
Box
结构体类型的数组p
,用于存储每箱糖果的信息。接着通过循环读取每箱糖果的价值v
和重量w
,并计算出每箱糖果的单位价值a
,存储到数组p
对应的元素中。
- 首先读取两个整数
-
选择糖果箱过程:
- 定义了两个变量
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。
- 如果是,说明可以直接选择整箱糖果,将该箱糖果的价值
- 首先通过一个内层循环遍历数组
- 定义了两个变量
-
输出部分:
最后通过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;
}