贪心算法:最优装载问题(C++实现)

概念

当一个问题具有最优子结构性质时,可用动态规划算法,有时会有更简单有效的算法,那就是贪心算法,贪心算法是通过一系列的选择来得到问题的解,贪心算法并不从整体最优上加以考虑,所做的选择只是在某种意义上的局部最优解。但对范围相当广的许多问题能产生整体最优解。在一些情况下,即使贪心算法不能得到整体最优解,但其最终结果却是最优解的很好的近似解。

贪心算法的基本要素

贪心选择性质:所求解的问题的整体最优解可以通过一系列局部最优的选择来,即贪心选择达到。贪心选择所依赖的是以前所做过的选择,而对以后所做的选择没有关系。

最优子结构性质:一个问题的最优解包含其子问题的最优解。

贪心算法与动态规划的区别

动态规划是通过自底向上的方式解决子问题,贪心算法是通过自顶向下的迭代方式做出贪心选择,求解问题的最优解。两共同点是都具有最优子结构性质。


最优装载问题:某艘船的载重量为C,每件物品的重量为wi,要将尽量多的物品装入到船上。

分析:贪心策略:每次都选择最轻的,然后再从剩下的n-1件物品中选择最轻的。

算法策略:把n件物品 从小到大排序,然后根据贪心策略尽可能多的选出前i个物品,直到不能装为止。

代码如下:

#include<iostream>
#include<algorithm>
#define MAXN 10000
using namespace std;
int main(){
    int c,n;    //c:船的最高载重量 n:古董数量
    int sum=0,weight=0; //sum:装入的古董数量 weight:装入的古董重量
    int w[MAXN];    //单个古董对应的重量
    cout<<"请输入最高载重量和需载的古董数目:"<<endl;
    cin>>c>>n;
    cout<<"请分别输入这些古董的重量:"<<endl;
    for(int i=1;i<=n;++i)
        cin>>w[i];
    sort(w+1,w+1+n);
    for(int i = 1 ; i<=n ; i++){
        weight += w[i]; //先将重量加进去
        if(weight >= c){
            if(weight == c)   //恰好装满时
                sum = i;
            else
                sum = i-1;  //超重了,需要减去一个
            break;
        }
    }
    cout<<"最多可以装"<<sum<<"个"<<endl;
    for(int i=1;i<=sum;++i)
        cout<<w[i]<<" ";
    return 0;
}

程序运行结果:

  • 7
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
贪心算法最优装载问题是指在一艘载重量为C的轮船上,有n个集装箱需要装载,其中第i个集装箱的重量为wi。装载时,必须将集装箱一件件地放入轮船中。对于每个集装箱,可以选择将其装入轮船或不装入轮船,但不能将其切割成小块进行装载。问应如何选择才能使轮船的装载量最大? 贪心算法最优装载问题的解题思路是每次选择当前剩余载重中能放置最重的货物放进去,这样可以尽可能地利用剩余的载重。 以下是使用c++实现贪心算法最优装载问题的代码示例: ```c++ #include<iostream> #include<algorithm> using namespace std; struct goods { int weight; //货物重量 int index; //货物编号 }; bool cmp(goods a, goods b) { //按货物重量从大到小排序 return a.weight > b.weight; } int main() { int n, c; //n为货物数量,c为轮船载重量 cin >> n >> c; goods *g = new goods[n]; for (int i = 0; i < n; i++) { cin >> g[i].weight; g[i].index = i; } sort(g, g + n, cmp); //按货物重量从大到小排序 int *result = new int[n]; int sum = 0; //记录当前已装载货物总重量 for (int i = 0; i < n; i++) { if (sum + g[i].weight <= c) { //若当前货物可以全部放进去,则全部放进去 result[g[i].index] = 1; sum += g[i].weight; } else { //否则只能放部分货物 result[g[i].index] = (c - sum) / g[i].weight; sum += result[g[i].index] * g[i].weight; } } cout << "最大装载量为:" << sum << endl; cout << "选择的货物编号为:"; for (int i = 0; i < n; i++) { if (result[i] == 1) { cout << i + 1 << " "; } } cout << endl; delete[]g; delete[]result; return 0; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值