C++贪心算法之最优装载问题

问题描述

在这里插入图片描述

题目分析

贪心问题最重要的是满足最优子结构性质和贪心选择性质。
最优装载问题要求在装在体积不受限制的情况下,尽可能多的集装箱装上轮船,也就是说我们需要让上船的集装箱数目最多,那么我们就应该尽量每次让重量最小的集装箱上船,这样的话船的最大重量就会剩余更多。所以这个问题我们利用贪心算法来每次找到当前重量最小的集装箱上船,直到船满或者集装箱重量大于船的剩余最大重量。
贪心选择性质:
我们写一个函数,将集装箱按照重量从小到大的顺序进行排列,(x1,x2,…xn)是最优装载问题的最优解,设k = min{i |xi=1}(1 <= i <= n),如果给定的最优装载问题有解,则1<=k<=n
①.当k=1时,(x1,x2,…,xn)是一个满足贪心选择性质的最优解。
②.当k>1时,取y1 = 1,yk = 0,yi = xi,1 < i <=n,i≠k,则:

在这里插入图片描述
因此,(y1,y2,…,yn)是所给最优装载问题的最优解
在这里插入图片描述
最优子结构性质
设(x1,x2,…,xn)是最有装载问题的满足贪心选择性质的最优解,则x1=1,(x2,x3,…,xn)是轮船装载重量为c-w1、待装载集装箱为{2,3,…,n}时相应最优装载问题的最优解。也就是说,最优装载问题具有最优子结构性质。

代码

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
//将集装箱重量从小到大排序,t存入的是排序后的集装箱的原有索引。
void Sort(int w[],int t[],int n)
{
    for(int i = 1;i < n;i++)
    {
        for(int j = 1;j < n - i;j++)
        {
            if(w[i] > w[j])
            {
                swap(w[i],w[j]);
                swap(t[i],t[j]);
            }
        }
    }
}
void Loading(int x[],int w[],int t[],int n,int c)
{
    int *t = new int[n + 1];
    Sort(w,t,n);
    for(int i = 1;i <= n;i++)
        x[i] = 0;//表示没有装载任何一个集装箱
    for(int i = 1;i <= n && w[t[i]] <= c;i++)
    {
        x[t[i]] = 1;//搬上船的集装箱在其对应位置标记为1
        c -= w[t[i]];
    }
}

总结

时间复杂度可以达到O(nlogn)(这里我用的是冒泡,大家可以使用归并排序,只需要O(nlogn))

发布了60 篇原创文章 · 获赞 2 · 访问量 1052

猜你喜欢

转载自blog.csdn.net/weixin_44755413/article/details/105641180