代码随想录算法训练营第四十二天| 背包问题

news/2024/11/30 13:52:07/

标准背包问题

有n件物品和一个最多能背重量为w 的背包。
第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

举一个例子:

背包最大重量为4。

物品为:

重量价值
物品0115
物品1320
物品2430

问背包能背的物品最大价值是多少?

  1. 确定dp数组以及下标的含义
    对于背包问题,有一种写法, 是使用二维数组,即
    dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少

  2. 递推公式
     可以有两个方向推出来dp[i][j],

  • 不放物品i:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以背包内的价值依然和前面相同。)
  • 放物品i:由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值

        所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
 

 3.dp数组初始化
        背包容量j为0的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为0。
        dp[0][j],即:i为0,存放编号0的物品的时候,各个容量的背包所能存放的最大价值。
        明显当 j < weight[0]的时候,dp[0][j] 应该是 0,因为背包容量比编号0的物品重量还小。
        当j >= weight[0]时,dp[0][j] 应该是value[0],因为背包容量放足够放编号0物品。

        其他下标应该初始化无所谓,因为根据递推公式看出:
        dp[i][j] 是由左上方数值推导出来了,故其他下标初始为什么数值都可以,因为都会被覆盖。

 4.确定遍历顺序
         有两个遍历的维度:物品与背包重量
          这里先遍历物品或遍历背包都可以
          递归公式中可以看出dp[i][j]是靠dp[i-1][j]和dp[i - 1][j - weight[i]]推导出来的。
          dp[i-1][j]和dp[i - 1][j - weight[i]] 都在dp[i][j]的左上角方向(包括正上方向)

先遍历物品,再遍历背包:

先遍历背包,再遍历物品:

5.举例推导dp数组

void test_2_wei_bag_problem1() {vector<int> weight = {1, 3, 4};vector<int> value = {15, 20, 30};int bagweight = 4;// 二维数组vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));// 初始化for (int j = weight[0]; j <= bagweight; j++) {dp[0][j] = value[0];}// weight数组的大小 就是物品个数for(int i = 1; i < weight.size(); i++) { // 遍历物品for(int j = 0; j <= bagweight; j++) { // 遍历背包容量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[weight.size() - 1][bagweight] << endl;
}int main() {test_2_wei_bag_problem1();
}

滚动数组版背包问题

动规五部曲分析如下:

  1. 确定dp数组的定义
    dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]。
  2. 一维dp数组的递推公式
    dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
  3. dp数组初始化
    均初始化为0,因为dp可以被覆盖
  4. 一维dp数组遍历顺序
    for(int i = 0; i < weight.size(); i++) { // 遍历物品for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);}
    }

    倒序遍历是为了保证物品i只被放入一次
    但如果一旦正序遍历了,那么物品0就会被重复加入多次!
    为什么二维dp数组历的时候不用倒序呢?
    因为对于二维dp,dp[i][j]都是通过上一层即dp[i - 1][j]计算而来,本层的dp[i][j]并不会被覆盖

  5. 举例推导dp数组
void test_1_wei_bag_problem() {vector<int> weight = {1, 3, 4};vector<int> value = {15, 20, 30};int bagWeight = 4;// 初始化vector<int> dp(bagWeight + 1, 0);for(int i = 0; i < weight.size(); i++) { // 遍历物品for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);}}cout << dp[bagWeight] << endl;
}int main() {test_1_wei_bag_problem();
}


http://www.ppmy.cn/news/550962.html

相关文章

计网复习题

一、单项选择题 OSI参考模型的物理层负责&#xff08;&#xff09;。 A&#xff0e;格式化报文 B&#xff0e;为数据选择通过网络的路由(网络层) C&#xff0e;定义连接到介质的特性 D&#xff0e;提供远程文件访问能力(应用层) 下列选项中&#xff0c;不属于网络体系结构中所…

Win10 安装arcgis10.2 for desktop需要microsoft.net framework 3.5 sp1或等效环境

PS C:\Windows\system32> DISM.EXE /Online /Add-Capability /CapabilityName:NetFx3~~~~ /Source:C:\Windows10\sources\sxs

解决:TIA Portal V17 WinCC BCA Ed 需要.NET 3.5SP1。请在此PC中启用....

解决&#xff1a;控制面板-程序-启用或关闭Windows功能

Windows Server 2008 R2上无法安装SP1

安装SP1主要是为了安装Visual Studio 2013。执行安装程序后系统提示"此service pack不适用于运行在此计算机上的windows 版本" 这篇名为“On a computer running Windows 7 and Windows Server 2008 R2, service pack 1 installation fails with error message 0x80…

【致远FAQ】V5V8.0sp1_单位管理员-流程督办监控-批量移交-待分配事项,是什么意思?

问题描述 单位管理员-流程督办监控-批量移交-待分配事项&#xff0c;是什么意思&#xff1f; 问题解答 抢单功能会用到待分配事项。 相关截图 技术无限&#xff0c;分享有限&#xff1b;如有疑惑&#xff0c;欢迎交流 ~

鸿蒙系统sp3什么意思,怎么看电脑系统是哪个版本的?例如SP2 SP3?

1.首先打开Windows/System32/找到EULA这个文本文档(即eula.txt)。打开在最后一行&#xff0c;有一个 EULAID:XPSP2_RM.0_PRO_RTL_CN。 2.如果你的EULAID和上面是一样的&#xff0c;那恭喜你了!你已经安装了集成SP2的Windows XP。里面没有SP1的痕迹&#xff0c;少了很多垃圾文件…

php中的资源是什么意思,PHP 和 COM

用户评论: microtrash at at gmail dot com (2008-07-09 11:29:52) In reference to question 1: On one project I had a dll that exposed certain functions I wished to call from within PHP. I created a PHP Module which had a matching function for each in the DLL.…

linux lts版本的区别,什么是Linux 发行版的 LTS 版本?

描述 在 Linux 的世界里,特别是谈到 Ubuntu 的时候,你会遇到 LTS( 长期支持(Long Term Support))这个词。 如果你是一个经验丰富的 Linux 用户,你可能知道 Linux 发行版的各个方面,比如 LTS 版本。但是,新用户或不太懂技术的用户可能不知道。 在这一章 Linux 黑话解释中,…