C++贪心算法之背包问题

问题描述

在这里插入图片描述

题目分析

这个问题和0-1背包问题有一定的差别,0-1背包问题的解决方法可以参加我的另一篇文章0-1背包问题
这两类问题都具有最优子结构性质。对0-1背包问题,设A是能够装入容量为c的背包的具有最大价值的物品集合,则为Aj = A-{j}是n-1个物1,2,…j-1,j+1…n可装入容量为c-wj的背包的具有最大价值的物品集合。对于背包问题,类似地,若它的一个最优解包含物品j,则从该最优解中拿出所含物品j的那部分重量w,剩余的将是n-1个原重物品1,2,…,j-1,j+1,…,n及重为wj-w的物品j中可装入容量为c-w的背包且具有最大价值的物品。
虽然这两个问题极为相似,但背包问题可以通过贪心算法解决求解,而0-1背包问题不能用贪心算法求解。用贪心算法解背包问题的基本步骤是:首先计算每种物品单位重量的夹着vi/wi;然后依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。若将这种物品全部装入背包后,背包内的物品总重量未超过c,则选择单位重量价值次高的物品并尽可能多地装入背包。以此策略,一直进行下去,直到背包装满为止。

代码

#include <iostream>
#include <algorithm>
using namespace std;
bool cmp(float a,float b)
{
    return a > b;
}
void Sort(int n,float v[],float w[])
{
    for(int i = 1;i <= n;i++)
    {
        v[i] = v[i] / w[i];
    }
    //将单位重量价值从大到小排序,并且将w也进行排序,排序的标准是单位重量价值高的排在前面
    for(int i = 1;i <= n - 1;i++)
    {
        for(int j = 0;j <= n - i;j++)
        {
            swap(v[i],v[j]);
            swap(w[i],w[j]);
        }
    }
}
void Knapsack(int n,float M,float v[],float w[],float x[])
{
    Sort(n,v,w);
    int i;
    for(i = 1;i <= n ;i++)
        x[i] = 0;
    float c = M;
    for(i = 1;i <= n ;i++)
    {
        if(w[i] > c)
            break;
        x[i] = 1;
        c -= w[i];
    }
    //包内的剩余重量对于当前价值物体能装的最大数量,1表示全部加入,这里会得到一个小数
    //小数表示将这一部分装入背包,例如0.5表示装一半进入背包
    if(i <= n)
        x[i] = c / w[i];
}

总结

时间复杂度主要取决我们使用什么样的排序算法,最好的是O(nlogn)

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

猜你喜欢

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