加勒比海盗船——最优装载问题-贪心算法

加勒比海盗船——最优装载问题

 在北美洲东南部,有一片神秘的海域,那里碧海蓝天、阳光明媚,这,正式传说中海盗最活跃的加勒比海(Caribbean Sea)。17世纪时,这里更是欧洲大陆的商旅舰队到达美洲的必经之地,所以当时的海盗活动非常猖獗,海盗们不仅攻击过往商人,甚至攻击英国皇家舰…… 
 有一天,海盗们截获了一艘装满各种各样古董的货船,每一件古董都价值连城,一旦打碎就失去了它的价值。虽然海盗船足够大,载重量为C,每件古董的重量为Wi,海盗们如何把尽可能多数量的宝贝装上海盗船呢?

问题分析

​ 首先要确定贪心策略,选择一个你认为最好的方案,运用贪心算法的缺点就是可能得不到最优解

​ 这道题要求古董的数量尽可能多,而船的容量是固定的,那么优先把重量小的物品放进去,在容量固定的情况下,装的物品最多,这里我就采用这种策略。

算法设计

​ 按照贪心策略,每次选择重量最小的古董放入(tmp代表古董的重量,ans代表已经装载的古董的个数)。

i 选择排序后第几个 装入重量tmp 是否超过载重量 ans
i=0 第一个 tmp=2 1
i=1 第二个 tmp=2+3=5 2
i=2 第三个 tmp = 5+4=9 3
i=3 第四个 tmp=9+5=14 4
i=4 第五个 tmp=14+7=21 5
i=5 第六个 tmp=21+10=31 超过 算法结束

伪代码详解

  1. 数据结构定义

    根据算法设计描述,我们用一维数组存储古董数量:

    double w[N];//一维数组存储古董的重量
    
  2. 按重量排序

    可以利用C++标准库中的排序函数sort,对古董的重量进行从小到大(非递减)排序。要使用此函数需要引入头文件<algorithm>

    语法描述为:

    sort(begin, end) //参数begin和end表示一个范围,分别为待排序数组的首地址和尾地址
        //sort函数默认升序
    
    sort(w, w+n);
    

大家都会了吗?自己亲手试试吧!先不要往下看,自己思考才是最好的😄

代码

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 101;//数组不用定义太多
double w[N];
int main()
{
    double c;
    int n;
    cout << "请输入载重量C及古董个数:" << endl;
    cin >> c >> n;
    cout << "请输入每个古董的重量,用空格分开:" << endl;
    for (int i = 0; i < n; i++) {
        cin >> w[i];
    }
    sort(w, w + n);
    double = tmp = 0.0;
    int ans = 0;
    for (int i = 0; i < n; i++) {
        tmp += w[i];
        if (tmp <= c) {
            ans ++;
        } else {
            break;
        }
    }
    cout << "能装入的古董最大数为Ans=";
    cout << ans << endl;
    return 0;
}

算法实现和测试

  1. 运行环境

    Visual Studio2019

  2. 输入

    请输入载重量C及古董个数:

    30 8

    请输入每个古董的重量,用空格分开:

    4 10 7 11 3 5 14 2

  3. 输出

重量C及古董个数:
>
> 30 8
>
> 请输入每个古董的重量,用空格分开:
>
> 4 10 7 11 3 5 14 2

  1. 输出

    能装入的古董最大数为Ans=5

posted @ 2020-03-20 14:30  Aeterna_Gungnir  阅读(877)  评论(0编辑  收藏  举报