0-1背包问题

这里写图片描述

状态 &转移

状态: f(i,C) 表示考虑将[0..i]的背包放入容量为C的背包的最大价值
状态转移:

f(i,C)=max{f(i1,C),v[i]+f(i1,C)}

解题代码

class Solution {

private:
    vector<vector<int>> memo;
    // [0..index] 放进容量为C的背包的最大价值
    int maxValue(const vector<int> &w, const vector<int> &v, int index, int C){

        if (index < 0 || C <= 0)return 0;

        if (memo[index][C] != -1)return memo[index][C];

        memo[index][C] = max(maxValue(w, v, index - 1, C),
            w[index] <= C ?
            v[index] + maxValue(w, v, index - 1, C - w[index]) :
            0);

        return memo[index][C];
    }

public:
    // 动态规划 (优化,只用一维数组存储)
    int knapsack2(const vector<int> &w, const vector<int> &v, int C){

        int n = w.size();
        if (n == 0)return 0;

        // memo[i][j] : 考虑将[0..i]物品放进容积为j的背包最大价值
        vector<int> memo(C + 1, -1);

        // 对基础问题进行设置,对[0,0]物品进行考虑,分别放进容量为[0..C]的背包的最大价值
        for (int j = 0; j <= C; j++)
            memo[j] = (j >= w[0] ? v[0] : 0);

        for (int i = 1; i < n; i++){
            for (int j = C; j >= w[i]; j--)
                memo[j] = max(memo[j], j >= w[i] ? v[i] + memo[j - w[i]] : 0);
        }

        return memo[C];
    }
    // 动态规划
    int knapsack1(const vector<int> &w, const vector<int> &v, int C){

        int n = w.size();
        if (n == 0)return 0;

        // memo[i][j] : 考虑将[0..i]物品放进容积为j的背包最大价值
        memo = vector<vector<int>>(n, vector<int>(C + 1, -1));

        // 对基础问题进行设置,对[0,0]物品进行考虑,分别放进容量为[0..C]的背包的最大价值
        for (int j = 0; j <= C; j++)
            memo[0][j] = (j >= w[0] ? v[0] : 0);

        for (int i = 1; i < n; i++){
            for (int j = 0; j <= C; j++)
                memo[i][j] = max(memo[i - 1][j], j >= w[i] ? v[i] + memo[i - 1][j - w[i]] : 0);
        }

        return memo[n-1][C];
    }
    int knapsack(const vector<int> &w, const vector<int> &v, int C){

        int n = w.size();

        memo = vector<vector<int>>(n, vector<int>(C + 1, -1));

        return maxValue(w, v, n - 1, C);
    }

    // 测试
    void test(){

        int weight[] = { 1, 2, 3 };
        int value[] = { 6, 10, 12 };

        vector<int> w(weight, weight + 3), v(value, value+3);

        cout << knapsack(w, v, 5) << endl;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值