0-1背包问题

问题:假设有一个容量为C的背包和n中不同的物品,每件物品重量为w(i)、价值v(i);现要在不超过背包容量的基础上,使得物品的总价值最大。

==状态F(n,C):==考虑将n个物品放进容量为C的背包,使得价值最大。
对第i件物品:
***F(i,c) = max( F(i-1, c), v(i) + F(i-1, c-w[i]) )***
本例中w = {1, 2, 3},对应v = {6, 10, 12}。
在这里插入图片描述

记忆化搜索

#include <iostream>
#include <vector>
#include <cassert>

using namespace std;

class Solution{

public:
    int knapsack01(const vector<int>& w, const vector<int>& v, int C){

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

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

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

private:
    vector<vector<int>> memo;

    //用[0...index]的物品填充容积为C的背包的最大价值
    int bestValue(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];

        int res = bestValue(w, v, index-1, c);
        if( c >= w[index] )
            res = max(res, v[index] + bestValue(w, v, index-1, c-w[index]));

        memo[index][c] = res;

        return res;
    }
};


int main(){

    vector<int> w = {1, 2, 3};
    vector<int> v = {6, 10, 12};
    int C = 5;

    int bestValue = Solution().knapsack01(w, v, C);

    cout<<"bestValue = "<<bestValue<<endl;

    return 0;
}

动态规划

#include <iostream>
#include <vector>
#include <cassert>

using namespace std;

class Solution{
//空间复杂度:O(n * C)
public:
    int knapsack01(const vector<int>& w, const vector<int>& v, int C){

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

        vector<vector<int>> memo(n, vector<int>(C+1, -1));
        //vector<int> memo(C+1, 0);
        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] = memo[i-1][j];
				if(j >= w[i])
					memo[i][j] = max(memo[i][j], v[i] + memo[i-1][j-w[i]]);
        }

        return memo[n-1][C];
    }

};



int main(){

    vector<int> w = {1, 2, 3};
    vector<int> v = {6, 10, 12};
    int C = 5;

    int bestValue = Solution().knapsack01(w, v, C);

    cout<<"bestValue = "<<bestValue<<endl;

    return 0;
}

鉴于上面空间复杂度为O(n * C),优化如下,此时空间复杂度O©。

#include <iostream>
#include <vector>
#include <cassert>

using namespace std;

class Solution{

public:
    int knapsack01(const vector<int>& w, const vector<int>& v, int C){

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

        //vector<vector<int>> memo(n, vector<int>(C+1, -1));
        vector<int> memo(C+1, 0);
        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], v[i] + memo[j-w[i]]);


        return memo[C];
    }

};



int main(){

    vector<int> w = {1, 2, 3};
    vector<int> v = {6, 10, 12};
    int C = 5;

    int bestValue = Solution().knapsack01(w, v, C);

    cout<<"bestValue = "<<bestValue<<endl;

    return 0;
}

声明:本文只是对波波老师授课内容总结,用于交流学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值