算法日记27:完全背包(DFS->记忆化搜索->倒叙DP->顺序DP->空间优化)

一、暴力搜索(DFS) O ( n 2 ) O(n^2) O(n2)
1.1)思路解析
1、注意和01背包的区别在于每个物品可以无限次选择
- 注意在完全背包中,当一个物品被选择过一次,我们仍然需要考虑是否继续选择这个物品
- 01背包:
max(dfs(x + 1, Spv), dfs(x + 1, Spv - vi[x]) + wi[x])//不选/选 - 完全背包:
max(dfs(x+1,Spv),dfs(x,Spv-vi[x])+wi[x]) //不选/选
- 01背包:
2、注意当选这个物品的时候,下一次应该继续考虑这个物品是否继续选择,所以是dfs(x,Spv-vi[x])+wi[x]
1.2)代码解析
#include <bits/stdc++.h>
using namespace std;const int N = 1007;
int vi[N],wi[N];
int n, v;int dfs(int x, int Spv)//从第x件物品开始,当前剩余容量为Spv
{if(x>n) return 0;if(Spv<vi[x]) return dfs(x+1,Spv); //物品体积太大,选不了else return max(dfs(x+1,Spv),dfs(x,Spv-vi[x])+wi[x]);
}void solve()
{cin >> n >> v;for (int i = 1; i <= n; i++){cin >> vi[i]>>wi[i];}int res=dfs(1,v);cout<<res<<'\n';
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int _ =1; //cin >> _;while (_--) solve();system("pause");return 0;
}
二、记忆化搜索 O ( n ∗ v ) O(n*v) O(n∗v)
2.1)思路解析
1、相比所谓的暴力搜索,优化了大量的时间复杂度(指数级->线性级)
2、所谓记忆化搜索,就是把DFS计算过的数据不再重复计算(用一个mem数组存储状态)
PS :记忆化数组的数据个数一般和DFS函数的参数一致
2.2)代码解析
#include <bits/stdc++.h>
using namespace std;const int N = 1007;
int vi[N],wi[N];
int n, v;
int mem[N][N];int dfs(int x, int Spv)//从第x件物品开始,当前剩余容量为Spv
{if(mem[x][Spv]) return mem[x][Spv];if(x>n) return 0;if(Spv>=vi[x]) //表示可以选{//选/不选return mem[x][Spv]=max(dfs(x,Spv-vi[x])+wi[x],dfs(x+1,Spv));}else //空间不够,不能拿当前物品{return mem[x][Spv]=dfs(x+1,Spv);}
}void solve()
{cin >> n >> v;for (int i = 1; i <= n; i++){cin >> vi[i]>>wi[i];}cout<<dfs(1,v)<<'\n';
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int _ =1; //cin >> _;while (_--) solve();system("pause");return 0;
}
三、倒序动态规划
3.1)思路解析
1、典型的空间换时间的做法,相比于搜索,节约了大量的时间复杂度
2、动态规划的for循环变量的参数,应该与DFS边界的限制的参数相同(例如:本题目中,边界与物品数量X、剩余的体积SPV有关)所以循环为n/v作为参数
- 因为在递归中,只有归才是产生答案的过程,所以可以从边界直接开始推出答案
3.2)代码解析
#include <bits/stdc++.h>
using namespace std;const int N = 1007;
int vi[N],wi[N];
int n, v;
int mem[N][N];
int f[N][N];// int dfs(int x, int Spv)//从第x件物品开始,当前剩余容量为Spv
// {
// if(mem[x][Spv]) return mem[x][Spv];
// if(x>n) return 0;// if(Spv>=vi[x]) //表示可以选
// {
// //选/不选
// return mem[x][Spv]=max(dfs(x,Spv-vi[x])+wi[x],dfs(x+1,Spv));
// }
// else //空间不够,不能拿当前物品
// {
// return mem[x][Spv]=dfs(x+1,Spv);
// }
// }void solve()
{cin >> n >> v;for (int i = 1; i <= n; i++){cin >> vi[i]>>wi[i];}//cout<<dfs(1,v)<<'\n';for(int i=1;i<=n;i++) //第几个物品{for(int j=0;j<=v;j++) //体积值{if(j>=vi[i]) 表示可以选f[i][j]=max(f[i-1][j],f[i][j-vi[i]]+wi[i]); //不选/选else //空间不够,不能拿当前物品f[i][j]=f[i-1][j];}}cout<<f[n][v];
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int _ =1; //cin >> _;while (_--) solve();system("pause");return 0;
}
四、顺序动态规划
4.1)思路解析
1、倒序遍历物品总是怪怪的,那么可不可以正序枚举呢,当然是可以的。
- PS:正序枚举相当于以 n − > 1 n->1 n−>1开始递归,此时边界刚刚好是为 1 1 1,所以循环从 1 1 1开始
4.2)代码解析
#include <bits/stdc++.h>
using namespace std;const int N = 1007;
int vi[N],wi[N];
int n, v;
int mem[N][N];
int f[N][N];// int dfs(int x, int Spv)//从第x件物品开始,当前剩余容量为Spv
// {
// if(mem[x][Spv]) return mem[x][Spv];// int sum=0;// if(x>n) sum= 0;
// else if(Spv<vi[x]) sum= dfs(x+1,Spv); //物品体积太大,选不了
// else sum= max(dfs(x+1,Spv),dfs(x,Spv-vi[x])+wi[x]);// mem[x][Spv]=sum;
// return sum;
// }void solve()
{cin >> n >> v;for (int i = 1; i <= n; i++){cin >> vi[i]>>wi[i];}for(int i=1;i<=n;i++) //变为正序递推{for(int j=0;j<=v;j++){if(j<vi[i]) f[i][j]=f[i-1][j]; //选不了else f[i][j]=max(f[i-1][j],f[i][j-vi[i]]+wi[i]); //不选/选}}cout<<f[n][v];
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int _ =1; //cin >> _;while (_--) solve();system("pause");return 0;
}
五、二维–>一维(空间优化)
5.1)思路解析
- 注意完全背包的二维的遍历应该是顺序枚举,为什么呢?
1、看下图,如果是正序的话,那么结果就会从:i 的状态–> i-1的状态
- 也就是从已经拿过第
i件商品的情况下,考虑在相同体积下是否要继续拿第i件商品
2、而物品 i i i的状态此时表明已经考虑过了 i i i这个物品,也就是已经选过了 i i i
3、那么此时就变成了从这个物品已经选过的状态—>下一个状态,那么此时,就表明这个物品就重复选了!!!,这就变成了完全背包!!!

5.2)代码解析
#include <bits/stdc++.h>
using namespace std;const int N = 1007;
int vi[N],wi[N];
int n, v;
int mem[N][N];
int f[N];// int dfs(int x, int Spv)//从第x件物品开始,当前剩余容量为Spv
// {
// if(mem[x][Spv]) return mem[x][Spv];
// if(x>n) return 0;// if(Spv>=vi[x]) //表示可以选
// {
// //选/不选
// return mem[x][Spv]=max(dfs(x,Spv-vi[x])+wi[x],dfs(x+1,Spv));
// }
// else //空间不够,不能拿当前物品
// {
// return mem[x][Spv]=dfs(x+1,Spv);
// }
// }void solve()
{cin >> n >> v;for (int i = 1; i <= n; i++){cin >> vi[i]>>wi[i];}//cout<<dfs(1,v)<<'\n';for(int i=1;i<=n;i++) //第几个物品{for(int j=0;j<=v;j++) //体积值{if(j>=vi[i]) f[j]=max(f[j],f[j-vi[i]]+wi[i]); //不选/选}}cout<<f[v];
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int _ =1; //cin >> _;while (_--) solve();system("pause");return 0;
}
总结:


相关文章:
算法日记27:完全背包(DFS->记忆化搜索->倒叙DP->顺序DP->空间优化)
一、暴力搜索(DFS) O ( n 2 ) O(n^2) O(n2) 1.1)思路解析 1、注意和01背包的区别在于每个物品可以无限次选择 注意在完全背包中,当一个物品被选择过一次,我们仍然需要考虑是否继续选择这个物品 01背包: …...
Linux 命令大全完整版(14)
5. 文件管理命令 chgrp(change group) 功能说明:变更文件或目录的所属群组。语 法:chgrp [-cfhRv][–help][–version][所属群组][文件或目录…] 或 chgrp [-cfhRv][–help][–version][–reference<参考文件或目录>][文件或目录…]补充说明&…...
基于 DeepSeek LLM 本地知识库搭建开源方案(AnythingLLM、Cherry、Ragflow、Dify)认知
写在前面 博文内容涉及 基于 Deepseek LLM 的本地知识库搭建使用 ollama 部署 Deepseek-R1 LLM知识库能力通过 Ragflow、Dify 、AnythingLLM、Cherry 提供理解不足小伙伴帮忙指正 😃,生活加油 我站在人潮中央,思考这日日重复的生活。我突然想,…...
Could not initialize class io.netty.util.internal.Platfor...
异常信息: Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class io.netty.util.internal.PlatformDependent0 Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.reflect.InaccessibleObjec…...
【书生大模型实战营】玩转HF/魔搭/魔乐社区-L0G4000
本文是书生大模型实战营系列的第4篇,本文的主题是:玩转HF/魔搭/魔乐社区。 1.开源大模型社区总览 开源不仅仅是一种技术模式,更是一种精神的体现。它打破了知识的壁垒,让技术平权成为可能。近年来,开源大模型社区蓬勃…...
2025年华为手机解锁BL的方法
注:本文是我用老机型测试的,新机型可能不适用 背景 华为官方已经在2018年关闭了申请BL解锁码的通道,所以华为手机已经无法通过官方获取解锁码。最近翻出了一部家里的老手机华为畅玩5X,想着能不能刷个系统玩玩,但是卡…...
了解 RAG 第二部分:经典 RAG 的工作原理
在本系列的第一篇文章中,我们介绍了检索增强生成 (RAG) ,解释了扩展传统大型语言模型 (LLM)功能的必要性。我们还简要概述了 RAG 的核心思想:从外部知识库检索上下文相关的信息,以确保 LLM 生成准确且最新的信息,而不会…...
50周学习go语言:第四周 函数与错误处理深度解析
第四周 函数与错误处理深度解析 以下是第4周函数基础的深度教程,包含两个完整案例和详细实现细节: 第四周:函数与错误处理深度解析 一、函数定义与参数传递 1. 基础函数结构 // 基本语法 func 函数名(参数列表) 返回值类型 {// 函数体 }// …...
debian 12安装 postgresql 17
按照官方文档安装,即可安装成功 https://www.postgresql.org/download/linux/debian/ 添加存储库 #添加存储库 sudo apt install -y postgresql-common#执行 存储库内 命令,自动处理某些东西 sudo /usr/share/postgresql-common/pgdg/apt.postgresql.o…...
C++....................4
1. using namespace std; class mystring { private:char* p;int len;// 辅助函数:复制字符串void copy(const char* source) {len strlen(source);p new char[len 1];strcpy(p, source);}// 辅助函数:释放内存void release() {if (…...
图书馆系统源码详解
本项目是一个基于Scala语言开发的图书馆管理系统。系统主要由以下几个部分组成:数据访问层(DAO)、数据模型层(Models)、服务层(Service)以及用户界面层(UI)。以下是对项目…...
Node.js中如何修改全局变量的几种方式
Node.js中如何修改全局变量。我需要先理解他们的需求。可能他们是在开发过程中遇到了需要跨模块共享数据的情况,或者想要配置一些全局可访问的设置。不过,使用全局变量可能存在一些问题,比如命名冲突、难以维护和测试困难,所以我得…...
基于javaweb的SpringBoot个人博客系统设计和实现(源码+文档+部署讲解)
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…...
厦大团队:DeepSeek大模型概念、技术与应用实践 140页PDF完整版下载
DeepSeek使用教程系列: 厦门大学: DeepSeek大模型概念、技术与应用实践 140页PDF完整版文件 厦大团队:DeepSeek大模型概念、技术与应用实践(140页PPT读懂大模型).pdf https://pan.baidu.com/s/1de4UIxqPsvMBIYcpen_M-…...
【Blender】二、建模篇--05,阵列修改器与晶格形变
阵列修改器是bender里面一个比较常用的修改器,所以我们单独开口来讲,我们会先从几片树叶出发,然后我们用阵列修改器把这几片树叶变成这样的造型和这样的造型。这两个造型分别就代表着阵列修改器最常用的两种偏移方法,我们现在就开始我们先来做几个树叶。 1.树叶建模 首先…...
#渗透测试#批量漏洞挖掘#畅捷通T+远程命令执行漏洞
免责声明 本教程仅为合法的教学目的而准备,严禁用于任何形式的违法犯罪活动及其他商业行为,在使用本教程前,您应确保该行为符合当地的法律法规,继续阅读即表示您需自行承担所有操作的后果,如有异议,请立即停止本文章读。 目录 一、漏洞概况 二、攻击特征 三、应急处置…...
【Python爬虫(23)】探秘Python爬虫数据存储:MongoDB实战指南
【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取ÿ…...
Pytorch使用手册-音频数据增强(专题二十)
音频数据增强 torchaudio 提供了多种方式来增强音频数据。 在本教程中,我们将介绍一种应用效果、滤波器、RIR(房间脉冲响应)和编解码器的方法。 最后,我们将从干净的语音合成带噪声的电话语音。 import torch import torchaudio import torchaudio.functional as Fprin…...
Linux 命令大全完整版(04)
1. 用户信息相关命令 who 功能说明:显示目前登入系统的用户信息。语 法:who [-Himqsw][--help][--version][am i][记录文件]补充说明:执行这项指令可得知目前有哪些用户登入系统,单独执行 who 指令会列出登入帐号、使用的终端…...
嵌入式Linux内核底层调试技术Kprobes
大家好,我是bug菌~ Kprobes 是 Linux 内核中一种动态插桩(Dynamic Instrumentation)技术,允许在不修改内核源码或重启系统的前提下,动态监控内核函数的执行。它是内核调试、性能分析和安全监控的重要工具。以下从技术…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
