Day42.01背包、分割等和子集
创始人
2024-03-22 12:14:41
0

Day42.01背包、分割等和子集

背包问题概述

01背包:n种物品,每种物品只有1个

完全背包:n种物品,每种物品无限个

多重背包:n种物品,每种物品个数各不相同

01背包

  1. dp[i][j]含义:i为[0,i]区间内的物品,任取,放到容量为j的背包里,最大价值
  2. 递推公式:对于当前dp[i][j],如果不放当前第i个物品,那么dp[i][j]就等于dp[i-1][j],和前面物品一样;如果放入当前物品,那么为了放入当前物品,背包预留空间至少要为j-weight[i],同时为了让背包内尽可能的多放物品,不留余地,空出来的位置,刚好够当前物品重量就够了,所以dp[i][j]等于dp[i-1][j-weight[i]]+value[i]。放不放入,取最大值,dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])
  3. dp数组初始化:i总是依赖i-1,j同样依赖于前面的值。因此i=0j=0时,都需要初始化。i为0,说明只有物品0,不论重量j取多少,只要大于等于当前重量,那么价值就是物品0的价值。如果j为0,说明背包容量为0,任何物品都放不下,价值总是为0
  4. 遍历顺序:外层物体遍历,内层背包容量遍历,从小到大;当然也可以调整循环顺序,只要两层都是从小到大就可以了。
void test_2_wei_bag_problem1() {vector weight = {1, 3, 4};vector value = {15, 20, 30};int bagweight = 4;// 二维数组vector> dp(weight.size(), vector(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();
}

01背包-状态压缩

观察dp递推公式,只看i,i只依赖于i-1,也就是只依赖于前一行,那就可以将二维降为一维。

  1. dp[j]的含义,容量为j的背包,所背的最大价值为dp[j]
  2. 递推公式:不放物品i,dp[j]=dp[j],就是第i-1号物品的最大价值;放物品i,dp[j]=dp[j-weight[i]]+value[i]。同样,要取最大值
  3. 初始化:目前dp数组只保留了容量这一维。dp[0]=0,对于非0下标,因为dp[j]的值要和其本身比大小,所以取非负的最小值就可以了,即全部初始化为0
  4. 遍历顺序:外层为物品遍历,从小到大;内层为容量遍历,从大到小,当前dp需要参考前面的值,但是因为少了一维当前层还是依赖于当前层,存在覆盖,如果从小到大遍历,前面的已经算过了,会重复计算。从大到小,一样依赖于前面的,但是先计算的是后面的值,前面的值不会覆盖。二维dp不会重复的原因是,当前值,依赖的是左上方的值,不在一个维度,所以不会覆盖。一维dp数组是重复利用的,新值与旧值要分开。因为压缩了i那一维,所以必须先遍历物品。
void test_1_wei_bag_problem() {vector weight = {1, 3, 4};vector value = {15, 20, 30};int bagWeight = 4;// 初始化vector 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;
}

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...