动态规划---混合背包

一:混合背包问题

(一)问题详述

 

(二)解决思路

将多重背包使用二进制拆分转换为01背包,使得只包含01背包和完全背包

(三)算法实现

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

const int N = 2020;

int n, m;
int f[N];    //全局变量,被初始化0

struct Good{
    int w, v;
    int s;        //-1为01背包,0完全背包,>0为多重背包
};

int main()
{
    vector<Good> goods;
    cin >> n >> m;    //初始化物品数量和背包容积

    for (int i = 1; i <= n; i++)    //初始化二进制拆分后的数量和价值
    {
        int w, v, s;
        cin >> w >> v >> s;
        
        if (s > 0){
            for (int k = 1; k <= s; k *= 2){    //注意:k从1开始,01背包会进行选或者不选,当所有拆分都不选择,那么就是没有选择这个物品
                s -= k;
                goods.push_back({ w*k, v*k, -1 });    //插入当前二进制拆分物品
            }
            if (s > 0)
                goods.push_back({ s*w, s*v, -1 });        //插入最后剩余的个数
        }
        else
            goods.push_back({ w, v, s });
    }
    //开始进行01背包求解问题
    for (auto g : goods){
        if (g.s==-1)    //01背包问题
            for (int j = m; j >= g.w; j--)    //注意:需要添加我们将判断条件提到这一步当中,保证剩余容量大于当前物品的体积
                f[j] = max(f[j], f[j - g.w] + g.v);    //对应不选和选
        else
            for (int j = g.w; j <= m; j++)    //注意:需要添加我们将判断条件提到这一步当中,保证剩余容量大于当前物品的体积
                f[j] = max(f[j], f[j - g.w] + g.v);    //对应不选和选
    }
        
    cout << f[m]<<endl;
    system("pause");
    return 0;
}

 

posted @ 2020-09-08 14:06  山上有风景  阅读(189)  评论(0)    收藏  举报