B3. 圣诞老人的礼物

【题目描述】

POJ4110 圣诞节来临了, 在城市 A 中圣诞老人准备分发糖果,现在有多箱不同的糖果: • 每箱糖果有自己的价值和重量 • 每箱糖果都可以拆分成任意散装组合带走 • 圣诞老人的驯鹿最多只能承受一定重量的糖果 • 请问圣诞老人最多能带走 多大价值的糖果

【输入格式】

• 第一行由两个部分组成, 分别为 • 糖果箱数正整数 n (1

【输出格式】

• 输出圣诞老人能带走的糖果的最大总价值, 保留 1 位小数 • 输出为一行, 以换行符结束

【样例输入】

4 15

100 4

412 8

266 7

591 2

【样例输出】

1193.0

【问题分析】

该段代码实现了一个简单的背包问题求解程序,我采用的是贪心算法的思路。程序从用户处获取物品的数量 n 和背包的容量 w,以及每个物品的价值 v 和重量 h,然后通过计算每个物品的单位价值(价值除以重量),按照单位价值从高到低的顺序选择物品放入背包,以求得背包能装入物品的最大总价值。

【数据结构设计】

头文件包含

  • 包含了输入输出流头文件 <iostream>,用于实现控制台的输入输出操作。
  • 包含了 <iomanip> 头文件,用于控制输出格式,在这里主要用于设置输出的精度。

全局变量定义

  • 定义了一个常量 Maxsize,表示数组的最大容量为 100,用于限制物品数量等相关数组的大小。
  • 定义了一个整型数组 S,并初始化为全 0,这个数组在后续的算法实现中用于标记某个物品是否已经被选择放入背包。

类定义

  • 定义了一个名为 ElemType 的类,用于表示物品的类型。类中有两个成员变量:value 表示物品的价值,weight 表示物品的重量,都是双精度浮点数类型。

函数定义

select 函数

该函数接受一个双精度数组 A 和数组大小 n,用于从数组 A 中选择未被标记(S[j]!= 1)且值最大的元素的下标。首先初始化一个临时最大值 x 为 0 和记录下标的 Index 为 0,然后遍历数组 A,当找到比当前最大值 x 更大且未被标记的元素时,更新 x 和 Index。最后将选中元素对应的 S 数组位置标记为 1,表示已被选择,并返回该元素的下标。

Maxvalue 函数

该函数接受双精度数组 A(存储物品单位价值)、数组大小 nElemType 类型数组 Q(存储物品的价值和重量信息)以及背包容量 w。通过多次调用 select 函数,按照单位价值从高到低的顺序选择物品放入背包。如果选中物品的重量小于等于背包剩余容量 w,则将该物品的价值累加到结果 result 中,并更新背包剩余容量 w;如果选中物品的重量大于背包剩余容量,则根据剩余容量按比例计算该物品能放入背包部分的价值并累加到 result 中,然后结束循环。最后返回背包能装入物品的最大总价值。

【源代码】

#include<iostream>
#include <iomanip>
using namespace std;


const int Maxsize = 100;
int S[Maxsize] = { 0 };
class ElemType
{
public:
    double value;
    double weight;
};

int select(double A[],int n)
{
    double x = 0;
    int Index = 0;
    for (int j = 0; j < n; j++)
    {
        if (A[j] > x && S[j]!=1)
        {
            x = A[j];
            Index = j;
        }
    }
    S[Index] = 1;
    return Index;
}

double Maxvalue(double A[],int n,ElemType Q[],int w)
{
    double result = 0;
    for (int i = 0; i < n; i++)
    {
        int y = select(A, n);
        if (Q[y].weight <= w)
        {
            result += Q[y].value;
            w = w- Q[y].weight;
        }
        else
        {
            result += A[y] * w;
            break;
        }
    }
    return result;
}
int main()
{
    ElemType Q[Maxsize];
    double A[Maxsize];
    double v, h;
    int n, w;
    cin >> n >> w;
    while(n < 1 || n>100 || w <= 0 || w > 10000)
    {
        cout << "输入超出范围,请重新输入:" << endl;
        cin >> n >> w;
    }
    for (int i = 0; i < n; i++)
    {
        cin >> v >> h;
         Q[i].value = v;
        Q[i].weight = h;
        A[i] = v / h;
    }
    cout<<fixed<< setprecision(1)<< Maxvalue(A, n, Q, w)<<endl;
    system("pause");
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值