【算法】动态规划之背包DP问题(2024.5.11)

 前言:

本系列是学习了董晓老师所讲的知识点做的笔记

董晓算法的个人空间-董晓算法个人主页-哔哩哔哩视频 (bilibili.com)

动态规划系列 

【算法】动态规划之线性DP问题-CSDN博客

01背包

步骤:

分析容量j与w[i]的关系,然后分析是否要放入背包

二维数组

for(int i=1; i<=n; i++)       //物品for(int j=1; j<=m; j++)     //容量if(j<w[i]) f[i][j]=f[i-1][j];            else f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+c[i]);

一维数组用逆序循环的原因

用一维数组f[i]只记录一行数据,让j值顺序循环,顺序更新f[j]值,f[j-w[i]]会先于f[j]更新,会出错。

如果j是逆序循环,f[j]会先于f[j-w[i]]更新

01背包使用的是上一层的值,如果顺序循环的话就会改变应有的值

for (int i = 1; i <= n; i++)//物品i
{for (int j = m; j >= w[i], j--)//容量j{f[j] = max(f[j], f[j - w[i]] + c[i])}
}
 

完全背包 

完全背包使用的是同一层的值,顺序循环的话改变值正是他所需要的,所以他可以顺序循环

for(int i=1; i<=n; i++)       //物品for(int j=1; j<=m; j++)     //容量if(j<w[i]) f[i][j]=f[i-1][j];            else f[i][j]=max(f[i-1][j],f[i][j-w[i]]+c[i]);
for (int i = 1; i <= n; i++)//物品i
{for (int j = w[i]; j <= m, j++)//容量j{f[j] = max(f[j], f[j - w[i]] + c[i])}
}

01背包和完全背包的区别

01背包第i件物品可以放入0个或者1个

完全背包第i件物品可以放入0个,1个,2个..... 

多重背包

01背包:第i种物品可以取0件、取1件。

多重背包:第i种物品可以取0件、取1件、取2件……取s件。

多重背包转化为01背包求解:把第i种物品换成s件01背包中的物品,每件物品的体积为k*v,价值为k*w(0≤k≤s)。

朴素算法

  //v[i],&w[i],&s[i])分别表示体积,价值,数量for(int i=1; i<=n; i++)               for(int j=0; j<=m; j++)               for(int k=0; k<=s[i]&&k*v[i]<=j; k++) f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);

二进制优化

int num = 1;
for (int i = 1; i <= n; i++)
{cin >> v >> w >> s;//体积,价值,数量for (j = 1; j <= s; j <<= 1){vv[num] = j * v;ww[num++] = j * w;s -= j;}if (s){vv[num] = s * v;ww[num++] = s * w;}
}
for (int i = 1; i < num; i++)for (int j = m; j >= v[i]; j--)f[j] = max(f[j], f[j - vv[i]] + ww[i]);

单调队列

前置知识 

【算法】用存入下标的方法来巧解单调队列-CSDN博客

 

(k-q[h])/v是还能放入物品的个数。f[k]=窗口中的最大值+还能放入物品的价值。 

混合背包 

题目:

思路

分类处理的思想:
1.利用多重背包的二进制优化,将多重背包转化为多个01背包。
2.用a,b,c三个数组来记录转化之后的所有背包的体积、价值、类型,c[i]==0表示完全背包,c[i]==1表示01背包。最后再做一遍,以c的值分为两类,做完全背包和01背包。

for (int i = 1; i <= n; i++) {scanf("%d%d%d", &v, &w, &s);if (s == 0) {     //完全背包a[num] = v;b[num] = w;c[num++] = 0; //背包类型 }else {         if (s == -1)s = 1;//01背包转多重背包int k = 1;while (s >= k) {//二进制拆分a[num] = k * v;b[num] = k * w;c[num++] = 1;s -= k; k <<= 1;}if (s) {a[num] = s * v;b[num] = s * w;c[num++] = 1;}}
}
for (int i = 1; i < num; i++) {if (c[i] == 1) //01背包for (int j = m; j >= a[i]; j--)f[j] = max(f[j], f[j - a[i]] + b[i]);else        //完全背包for (int j = a[i]; j <= m; j++)f[j] = max(f[j], f[j - a[i]] + b[i]);
}

二维费用背包 

f[i][k]: 背包容量为j,且承重为k时,能放入的最大价值。

f[V][M]: 背包容量为V,且承重为M时能放入的最大价值,即全局最优解。

  cin>>n>>V>>M;for(int i=1; i<=n; i++){  //物品 cin>>v>>m>>w;for(int j=V; j>=v; j--) //体积for(int k=M; k>=m; k--) //重量f[j][k]=max(f[j][k],f[j-v][k-m]+w);
}cout<<f[V][M];

分组背包

分组背包与多重背包的区别是分组背包在每一个组中只能选一个 

决策在前,体积在后的方法是错误的(用同一组的物品来更新了),积前策后才是对的

二维决策:同一个组里面的物品只能选一个

一维决策:个数

for (int i = 1; i <= n; i++)     //物品组
for (int j = 1; j <= V; j++)     //体积
for (int k = 0; k <= s[i]; k++)  //决策
if (j >= v[i][k])
f[i][j] = max(f[i][j], f[i - 1][j - v[i][k]] + w[i][k]);
for (int j = 1; j <= s; j++) 
cin >> v[j] >> w[j];
for (int j = V; j >= 1; j--) //体积
for (int k = 0; k <= s; k++) //决策
if (j >= v[k]) f[j] = max(f[j], f[j - v[k]] + w[k]);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/690551.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全新神经网络架构KAN——本文用于学习与探索

论文地址&#xff1a;https://arxiv.org/pdf/2404.19756 Github&#xff1a;GitHub - KindXiaoming/pykan: Kolmogorov Arnold Networks 文档说明&#xff1a;Welcome to Kolmogorov Arnold Network (KAN) documentation! — Kolmogorov Arnold Network documentation 本文仅…

SQLite性能测试(插入)

最近一直在思考一个问题&#xff0c;SQLite 做到这么轻量级&#xff0c;那它注定不会像 MySql 一样强性能&#xff0c;那么它的性能怎么样呢&#xff1f;并发量多高呢&#xff1f; 官方解释&#xff1a; About SQLite 最大数据库大小&#xff1a;281TB 最大行大小&#xff1…

【C语言题解】输入n(1~9),再输入n个长度不超过50的字符串,给这n个字符串排序并输出它们

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f308;感谢大家的阅读、点赞、收藏和关注 解题思路&#xff1a; 首先&#xff1a;使用一个二维字符数组来存储输入的字符串。由于n的范围是1到9&#xff0c;我们可以直接定义一…

进程间通信:连接不同程序世界的桥梁

目录 一、进程间通信的重要性 二、常见的进程间通信方式 三、进程间通信的目的 四、进程间通信的本质 在计算机编程的领域中&#xff0c;进程间通信&#xff08;Inter-Process Communication&#xff0c;IPC&#xff09;是一个至关重要的概念。当我们在操作系统中运行多个程…

Golang | Leetcode Golang题解之第83题删除排序链表中的重复元素

题目&#xff1a; 题解&#xff1a; func deleteDuplicates(head *ListNode) *ListNode {if head nil {return nil}cur : headfor cur.Next ! nil {if cur.Val cur.Next.Val {cur.Next cur.Next.Next} else {cur cur.Next}}return head }

基于Python+Django+MySQL实现Web版的增删改查

Python Web框架Django连接和操作MySQL数据库学生信息管理系统(SMS),主要包含对学生信息增删改查功能&#xff0c;旨在快速入门Python Web。 开发环境 开发工具&#xff1a;Pycharm 2020.1开发语言&#xff1a;Python 3.8.0Web框架&#xff1a;Django 3.0.6数据库&#xff1a;…

【SpringBoot】Redis Lua脚本实战指南:简单高效的构建分布式多命令原子操作、分布式锁

文章目录 一.Lua脚本1.Lua特性2.Lua优势 二.Lua语法1.注释2.变量3.数据类型&#xff1a;3.1.基本类型3.2.对象类型&#xff1a;表&#xff08;table&#xff09; 4.控制结构&#xff1a;4.1.条件语句: 使用if、else和elseif来实现条件分支。4.2.循环结构&#xff1a;Lua支持for…

Vue中进行粘贴板粘贴数据(图片、文字等)

在页面中如果需要进行粘贴数据&#xff0c;那么就要读取系统粘贴板clipboard&#xff0c;通过此Api来进行粘贴板数据的操作。 目录: 一.封装相关函数1.示例代码&#xff1a;2.代码解释&#xff1a; 二.页面中进行粘贴1.代码示例&#xff1a;2.代码解释&#xff1a; 三.运行结果…

使用html和css实现个人简历表单的制作

根据下列要求&#xff0c;做出下图所示的个人简历&#xff08;表单&#xff09; 表单要求 Ⅰ、表格整体的边框为1像素&#xff0c;单元格间距为0&#xff0c;表格中前六列列宽均为100像素&#xff0c;第七列 为200像素&#xff0c;表格整体在页面上居中显示&#xff1b; Ⅱ、前…

Ansible----playbook模块之templates模块、tags模块、roles模块

目录 引言 一、templates模块 &#xff08;一&#xff09;关键信息 &#xff08;二&#xff09;实际操作 1.定义主机组 2.设置免密登录 3.分别建立访问目录 4.定义模板文件 5.创建playbook文件 6.执行剧本 7.验证结果 二、tags模块 &#xff08;一&#xff09;创建…

i春秋-GetFlag

题目 考点 sql注入&#xff0c;md5加密&#xff0c;代码审计&#xff0c;利用eval函数 解题 参考wp https://www.cnblogs.com/qiaowukong/p/13630130.html找md5值 看见验证码中的提示&#xff0c;就是去找一个md5值前六位是指定值的数&#xff08;严格来说不一定是数&…

虚拟化技术 安装和配置StartWind iSCSI目标服务器

一、实验内容 安装StartWind iSCSI目标服务器配置StartWind iSCSI目标服务器 二、实验主要仪器设备及材料 安装有64位Windows操作系统的台式电脑或笔记本电脑&#xff0c;建议4C8G或以上配置已安装vSphere Client已创建虚拟机并在其上安装CentOS6.5StarWind安装介质starwind.…