背包问题(greedy+dfs+dp)

背包问题(部分+01 greedy+dfs+dp)

部分背包问题

(背包重量符合要求=》背包价值max)
部分背包问题,指的是物品可以以任何大小放到背包中。
这个问题相较于0-1背包问题要更简单,包是可以在物体总质量>背包质量的情况下塞满的!所以单位重量价值越大越好!(用结构体去表示物体的质量、价值和单位价值)

使用贪心算法解决此问题:

#include <algorithm>
#include <iostream>
#include <map>

using namespace std;
int w[5] = {3, 4, 6, 10, 7};     //重量
int v[5] = {15, 16, 18, 25, 14}; //价
//结构体
typedef struct
{
    int weight;
    int value;
    float vperw;
} good;
//比较
bool cmp(good a, good b)
{
    return a.vperw > b.vperw;
}
int main()
{
    int w[5] = {3, 4, 6, 10, 7};     //重量
    int v[5] = {15, 16, 18, 25, 14}; //价值
    int maxvalue = 0;
    int W;
    cin >> W; //输入限制的背包总质量
    vector<good> thing;
    good g;
    for (int i = 0; i < 5; i++)
    {
        g.value = v[i];
        g.weight = w[i];
        g.vperw = v[i] / w[i];
        thing.push_back(g);
    }
    sort(thing.begin(), thing.end(), cmp);
    for (int i = 0; i < 5; i++)
    {
        maxvalue += (W > thing[i].weight) ? thing[i].weight * thing[i].vperw : W * thing[i].vperw;
        cout << "装载物品价值:" << thing[i].value;
        if (W > thing[i].weight)
        {
            cout << "  装载物品质量:" << thing[i].weight;
        }
        else
        {
            cout << "  装载物品质量:" << W;
        }
        cout << endl;

        W -= thing[i].weight;
        if (W <= 0)
        {
            break;
        }
    }
    cout << "最大价值:" << maxvalue;
}

测试结果

01背包问题

顾名思义就是物品只有两种状态,放或者不放。
举个老师课件上例子:
在这里插入图片描述
在这个例子可以看到背包的容量是50,三件物品的容量是10,20,30。倘若按照部分背包问题进行求解,可以得到将item1、item2放入背包中,因为它们的单位价值较高,但这时item3就放不进去了,所以贪心算法无法解决01背包问题,我们要对背包容量和物品容量及价值做一个综合的考量,每一个物品都有放和不放的两种状态,需要我们去尝试和试探。试探一次,容易想到回溯dfs,这是这类问题的一种解法,在这里给出dfs解法。

#include<iostream>
using namespace std;
int n=0;
const int maxn = 100;
int w[maxn];//物品重量
int v[maxn];//物品价值
int C=0;//背包容量
int maxvalue=0;//当前最大价值


void dfs(int index,int sumw,int sumv){
    //dfs终止条件
    if(index==n){//n为物品个数
        if(sumw<=C&&sumv>=maxvalue){//<=C
            maxvalue = sumv;
        }
        return;
    }
    //选第i件物品
    dfs(index + 1, sumw + w[index], sumv + v[index]);
    //不选第i件物品
    dfs(index + 1, sumw, sumv);
}

int main()
{
    cout << "输入物品个数:";
    cin >> n;
    cout << "输入背包容量:";
    cin >> C;
    cout << "依此输入物品重量:";
    for (int i = 0; i < n;i++){
        cin >> w[i];
    }
    cout << "依此输入物品价值:";
    for (int i = 0; i < n;i++){
        cin >> v[i];
    }
    dfs(0, 0, 0);
    cout << "最大价值是" << maxvalue;

}

dfs有自己的书写格式

dfs(){
	if(终止条件) return;
	dfs()

下面考虑使用动态规划解决这个问题:
动态规划有两个前提条件:重叠子问题和最优子结构。
我们来观察01背包问题:
使用 dp[i-1][w] 表示前i-1个物品放入容量为w的背包的最大价值。
那么放入第i物品时,就有两种考虑情况:

  • 放了!那么dp[i][w]=dp[i][w-w[i]]+v[i]
  • 没放!那么dp[i][w]=dp[i-1][w]

这个时候最优出来做决定,选择max即可,再加上边界条件即可。

int main()
{
    int n, w;//物品数目,背包容量
    cout << "请输入物品数目:";
    cin >> n;
    cout<< "请输入背包容量:";
    cin >> w;
    int weight[n];
    int value[n];
    cout << "依次输入物品重量:";
    for (int i = 1; i <=n; i++)
    {
        cin >> weight[i];
    }
    cout << "依次输入物品价值:";
    for (int i = 1; i <= n; i++)
    {
        cin >> value[i];
    }
    //dp运算
    for (int i = 0; i <= n; i++)
    {

        for (int j = 0; j <= w; j++)
        {
             if(i==0||j==0){
                 dp[i][j] = 0;
             }
             if(j<weight[i]){
                 dp[i][j] = dp[i - 1][j];
             }
             else{
                 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
             }
        }
    }
    cout << "最大价值:" << dp[n][w];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于贪心算法解决01背包问题的具体操作如下: 1. 首先,根据背包问题的要求,将物品按照单位重量的价值从大到小进行排序。 2. 然后,依次将物品放入背包中,直到背包无法再放入为止。每次选择单位重量价值最高的物品放入背包。 3. 如果当前物品无法完全放入背包,则将物品按照比例切割,只放入一部分。 4. 重复步骤2和步骤3,直到背包无法再放入物品或者所有物品都已经放入背包。 下面是一个基于贪心算法解决01背包问题的Python代码示例: ```python def knapsack_greedy(weights, values, capacity): n = len(weights) ratio = [values[i] / weights[i] for i in range(n)] index = sorted(range(n), key=lambda k: ratio[k], reverse=True) total_value = 0 selected_items = [] for i in index: if weights[i] <= capacity: total_value += values[i] selected_items.append(i) capacity -= weights[i] else: fraction = capacity / weights[i] total_value += fraction * values[i] selected_items.append(i) break return total_value, selected_items weights = [10, 20, 30] values = [60, 100, 120] capacity = 50 max_value, selected_items = knapsack_greedy(weights, values, capacity) print("Max value: ", max_value) print("Selected items: ", selected_items) ``` 该代码中,weights和values分别表示物品的重量和价值,capacity表示背包的容量。函数knapsack_greedy根据贪心算法的原理,计算出背包中能够放入的物品以及对应的总价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值