背包问题详解-动态规划

本文详尽探讨背包问题,包括01背包、完全背包和多重背包问题的动态规划解决方案。通过状态转移方程分析,展示了如何通过空间优化减少复杂度,同时介绍了将不同背包问题转化为01背包问题的技巧。
摘要由CSDN通过智能技术生成

前言
网上的背包问题已经写了很多,但是感觉不是很详细,很多细节虽然提了一下,但是没有讲透彻,因此我写下这篇笔记。
——————————————————————————————————————

背包问题(knapsack problem)是一个非常典型的考察动态规划应用的题目,对其加上不同的限制和条件,可以衍生出诸多变种,若要全面理解动态规划,就必须对背包问题了如指掌。

01背包问题

最基本问题描述指01背包问题

一共有N件物品,第i(i从1开始)件物品的重量为w[i],价值为v[i]。在总重量不超过背包承载上限C的情况下,能够装入背包的最大价值是多少?

暴力法

我们的目标是书包内物品的总价值,而变量是物品和书包的限重,所以我们可定义状态dp:

dp[i][j] 表示将前i件物品装进限重为j的背包可以获得的最大价值, 0<=i<=N, 0<=j<=W

首先将dp[0][0]、dp[0][1]....dp[0][W]初始化为0,表示将前0个物品(即没有物品)装入书包的最大价值为0。那么当 i > 0 时dp[i][j]有两种情况:

  • 1 不装入第i件物品,即dp[i−1][j]
  • 2 装入第i件物品(前提是能装下),即dp[i−1][j−w[i]] + v[i]

状态转移方程为:

dp[i][j] = max(dp[i−1][j], dp[i−1][j−w[i]]+v[i]) // j >= w[i]

注意这里要保证j>=w[i],因此我们可以得到:

int knapsack(vector<int> v, vector<int> w, int n, int C )
{
   
	//初始化dp的值为0
    vector<vector<int> > dp(n, vector<int>(C + 1,0));
    
    for(int i = 1; i < =n; i++){
   
        for(int j = 1; j <= C ; j++){
   
            if(j < w[i]){
   
                dp[i][j] = f[i - 1][j]
            }
            else{
   
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
            }
        }
    }
    return dp[n ][C];
}

此时的时间和空间复杂度都是O(nC)

空间优化

我们来看一下这个程序是怎么运行的,如图所示,
N=5,C=11, value ={1,6,18,22,28},weight={1,2,5,6,7}
N=5,C=11
程序首先求dp[1][1]=1, dp[1][2]=1......dp[1][11]=1这一行的数据&#x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值