完全背包例题(滚动数组)

简介: 完全背包例题(滚动数组)

1. 例题


题目

有N件物品和一个最多能背重量为 W 的背包。第 i ii 件物品的重量是w e i g h t [ i ] ,得到的价值是 v a l u e [ i ] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。

完全背包和01背包问题唯一不同的地方就是,每种物品有无限件。同样leetcode上没有纯完全背包问题,都是需要完全背包的各种应用,需要转化成完全背包问题,所以我这里还是以纯完全背包问题进行讲解理论和原理。

在下面的讲解中,我依然举这个例子:

背包最大重量为4.

物品为:


重量 价值
物品0 1

15

物品1 3

20

物品2 4

30

每件商品都有无限个


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


思路

01背包和完全背包唯一不同在于遍历顺序上


01背包核心代码

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]);
  }
}


01背包内嵌的循环是从大到小遍历,为了保证每个物品仅被添加一次


举例:


假设物品0重量 w e i g h t [ 0 ] = 1,价值 v a l u e [ 0 ] = 15

如果是正序遍历


d p [ 1 ] = d p [ 1 − w e i g h t [ 0 ] ] + v a l u e [ 0 ] = 15

d p [ 2 ] = d p [ 2 − w e i g h t [ 0 ] ] + v a l u e [ 0 ] = 30


在第一行运行后 d p [ 1 ] dp[1]dp[1] 的状态已经发生改变,意味着已经放了物品0,而第二行运行后,叠加了改变后的 d p [ 1 ] dp[1]dp[1],意味着物品0被放了两次。


那么为什么之前在写二维数组的时候是正序的?


因为我们实际求的是上一行的状态,也就是不放当前物品的情况,只不过在滚动数组中,压缩了状态。也即当前元素的公式被运行后,当前元素的状态(在当前行,包括物品0)覆盖了先前状态(在上一行,不含物品0),所以一维中倒序是为了保证物品只被放入一次!

而完全背包的物品是可以添加多次的,所以要从小到大去遍历


for(int i = 0; i < weight.size(); i++)   // 遍历物品
{ 
  for(int j = weight[i]; j >= bagWeight; j++) // 遍历背包容量
  { 
    dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
  }
}


遍历顺序是否强制先遍历物品,再遍历背包容量?


在01背包的一维数组中必须先遍历物品,再遍历背包容量。


而在完全背包的一维数组中,循环嵌套顺序却无所谓。


因为 dp[j] 是根据它同行的左边的元素推出来的,而无论哪种顺序,它的左值都是更新过的,可用的。

但先后顺序可以颠倒的前提是纯完全背包问题!题目变化的可能就不行


代码展示

#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
void test_CompletePack()
{
    vector<int> weight = {1, 3, 4};
    vector<int> value = {15, 20, 30};
    int bagWeight = 4;
    vector<int> dp(bagWeight + 1);
    for (int i = 0; i < weight.size(); i++)
    {
        for (int j = weight[i]; j <= bagWeight; j++)
        {
            dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
        }
    }
    cout << dp[bagWeight];
}
int main()
{
    test_CompletePack();
    return 0;
}
目录
相关文章
|
并行计算 开发工具 C++
无所不谈,百无禁忌,Win11本地部署无内容审查中文大语言模型CausalLM-14B
目前流行的开源大语言模型大抵都会有内容审查机制,这并非是新鲜事,因为之前chat-gpt就曾经被“玩”坏过,如果没有内容审查,恶意用户可能通过精心设计的输入(prompt)来操纵LLM执行不当行为。内容审查可以帮助识别和过滤这些潜在的攻击,确保LLM按照既定的安全策略和道德标准运行。 但我们今天讨论的是无内容审查机制的大模型,在中文领域公开的模型中,能力相对比较强的有阿里的 Qwen-14B 和清华的 ChatGLM3-6B。 而今天的主角,CausalLM-14B则是在Qwen-14B基础上使用了 Qwen-14B 的部分权重,并且加入一些其他的中文数据集,最终炼制了一个无内容审核的
无所不谈,百无禁忌,Win11本地部署无内容审查中文大语言模型CausalLM-14B
|
11月前
|
存储 算法
细谈多重背包问题
细谈多重背包问题
细谈多重背包问题
|
11月前
|
人工智能 C++
第十四届蓝桥杯省赛大学B组(C/C++)整数删除
第十四届蓝桥杯省赛大学B组(C/C++)整数删除
|
5月前
|
关系型数据库 MySQL Linux
CentOS 7系统下详细安装MySQL 5.7的步骤:包括密码配置、字符集配置、远程连接配置
以上就是在CentOS 7系统下安装MySQL 5.7的详细步骤。希望这个指南能帮助你顺利完成安装。
1448 26
|
11月前
|
Java Windows
如何在windows上运行jar包/JAR文件 如何在cmd上运行 jar包 保姆级教程 超详细
本文提供了一个详细的教程,解释了如何在Windows操作系统的命令提示符(cmd)中运行JAR文件。
5438 1
|
存储 定位技术
【天梯赛】L2-048 寻宝图 (DFS做法)
遇到一个非'0'字符(也就是'1'和 宝藏'2'到'9')就让ans++,同时将这个非'0'字符染色为'0',然后往四个方向(上、下、左、右)搜索,这里的目的是那一片岛屿(也就是那一片为'1'的部分)都染色为‘0’。本题就请你统计一下,给定的地图上一共有多少岛屿,其中有多少是有宝藏的岛屿。为了判断有宝藏的岛屿,这里我开了一个全局变量f来判断这一片岛屿是否有宝藏(也就是有无字符'2'-'9'),当搜到字符'2'~'9'时就将f标记为1。在一行中输出 2 个整数,分别是岛屿的总数量和有宝藏的岛屿的数量。
300 5
|
数据采集 XML 数据挖掘
构建高效Python爬虫:探索BeautifulSoup与Requests库的协同工作
【7月更文挑战第31天】在数据驱动的世界里,掌握网络数据采集技术变得尤为重要。本文将深入探讨如何利用Python语言中的BeautifulSoup和Requests库来构建一个高效的网络爬虫。我们将通过实际案例,展示这两个库如何在爬取网页数据时相互配合,以及如何通过简单的编码实现数据的精准抓取。文章不仅提供代码示例,还讨论了在使用这些工具时应注意的一些常见陷阱和最佳实践。无论你是数据分析师、研究人员还是对爬虫技术感兴趣的程序员,这篇文章都将为你提供一个清晰的指导框架,帮助你快速入门并提高你的爬虫技能。
235 1
|
存储 SQL Oracle
关系型数据库Oracle归档日志备份
【7月更文挑战第19天】
273 5
|
测试技术
蓝桥杯真题讲解——积木画
蓝桥杯真题讲解——积木画
208 0
|
存储 Kubernetes Cloud Native
解读K8s Pod的13种典型异常
在K8s中,Pod作为工作负载的运行载体,是最为核心的一个资源对象。Pod具有复杂的生命周期,在其生命周期的每一个阶段,可能发生多种不同的异常情况。K8s作为一个复杂系统,异常诊断往往要求强大的知识和经验储备。结合实战经历以及EDAS用户真实场景的归纳,我们总结了K8s Pod的13种常见异常场景,给出各个场景的常见错误状态,分析其原因和排查思路。
1642 110
解读K8s Pod的13种典型异常