当前位置: 首页 > news >正文

day43【代码随想录】动态规划之一和零、完全背包理论基础

文章目录

  • 前言
  • 一、一和零(力扣474)
  • 二、完全背包


前言

1、一和零
2、完全背包理论基础


一、一和零(力扣474)

求装满这个背包最多有多少个物品
给你一个二进制字符串数组 strs 和两个整数 m 和 n 。

请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。

如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。
在这里插入图片描述

背包容量是二维的 m个0 n个1 限制
思路:
动规五部曲
1、确定dp[]数组以及下标含义
dp[i][j]:i个0 j个1 最多装了dp[i][j]个物品

2、确定递推公式
dp[i][j] 可以由前一个strs里的字符串推导出来,strs里的字符串有zeroNum个0,oneNum个1。

dp[i][j] 就可以是 dp[i - zeroNum][j - oneNum] + 1。

然后我们在遍历的过程中,取dp[i][j]的最大值。

所以递推公式:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);

对比下01背包的递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

对比一下就会发现,字符串的zeroNum和oneNum相当于物品的重量(weight[i]),字符串本身的个数相当于物品的价值(value[i])。

这就是一个典型的01背包! 只不过物品的重量有了两个维度而已。

3、dp数组如何初始化

01背包的dp数组初始化为0就可以。
4、确定遍历顺序
外层for循环遍历物品,内层for循环遍历背包容量且从后向前遍历

5、举例推导dp数组
以输入:[“10”,“0001”,“111001”,“1”,“0”],m = 3,n = 3为例
最后dp数组的状态如下所示:
在这里插入图片描述

class Solution {public int findMaxForm(String[] strs, int m, int n) {int[][] dp = new int[m+1][n+1];int oneNum;int zeroNum;for(int x = 0; x<strs.length; x++){oneNum = 0;zeroNum = 0;for(char ch : strs[x].toCharArray()){if( ch == '0'){zeroNum++;}else oneNum++;}for(int i=m;i>=zeroNum;i--){for(int j=n;j>=oneNum;j--){dp[i][j] = Math.max(dp[i][j],dp[i-zeroNum][j-oneNum]+1);}}}return dp[m][n];}
}

在这里插入图片描述

二、完全背包

完全背包和01背包的区别所在: 物品在完全背包中可以使用无数次。

而在01背包一维dp数组中,倒序遍历背包容量就是为了保证每个物品只取一次,那么如何能让这个物品无限次使用呢?改为正序遍历

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

遍历顺序:
两层for循环可以相互颠倒
遍历物品在外层循环,遍历背包容量在内层循环(按行),状态如图:
在这里插入图片描述

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

遍历背包容量在外层循环,遍历物品在内层循环(按列),状态如图:
在这里插入图片描述

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

完整代码:

//先遍历物品,再遍历背包
private static void testCompletePack(){int[] weight = {1, 3, 4};int[] value = {15, 20, 30};int bagWeight = 4;int[] dp = new int[bagWeight + 1];for (int i = 0; i < weight.length; i++){ // 遍历物品for (int j = weight[i]; j <= bagWeight; j++){ // 遍历背包容量dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);}}for (int maxValue : dp){System.out.println(maxValue + "   ");}
}

http://www.lryc.cn/news/9763.html

相关文章:

  • GEE学习笔记 七十八:干涸的洪泽湖
  • 双指针【灵神基础精讲】
  • tushare量化数据库模块怎么分析?
  • 模型转换 PyTorch转ONNX 入门
  • 【深度学习】激活函数
  • 【新2023】华为OD机试 - 数字的排列(Python)
  • [oeasy]python0085_ASCII之父_Bemer_COBOL_数据交换网络
  • volatile,内存屏障
  • 【ESP 保姆级教程】玩转emqx MQTT篇① —— 系统主题、延迟发布、服务器配置预算、常见问题
  • 第48讲:SQL优化之ORDER BY排序查询的优化
  • [Datawhale][CS224W]图机器学习(三)
  • 2023版最新最强大数据面试宝典
  • CSS 中的 BFC 是什么,有什么作用?
  • 总结在使用 Git 踩过的坑
  • 从 HTTP 到 gRPC:APISIX 中 etcd 操作的迁移之路
  • 【C语言每日一题】——倒置字符串
  • Native扩展开发的一般流程(类似开发一个插件)
  • 【新解法】华为OD机试 - 任务调度 | 备考思路,刷题要点,答疑,od Base 提供
  • Spring3定时任务
  • 数据库版本管理工具Flyway应用研究
  • 更换 Ubuntu 系统 apt 命令安装软件源
  • 2023年可见光通信(LiFi)研究新进展
  • Greenplum的两阶段提交
  • 多元回归分析 | CNN-BiLSTM卷积双向长短期记忆神经网络多输入单输出预测(Matlab完整程序)
  • git命令行推送本地分支到远程仓库
  • 在vscode中使用Typescript并运行
  • 【C++提高编程】C++全栈体系(十九)
  • Java版电能表协议解析源码(DL/T645-2007)、Modbus串口虚拟工具、网络串口调试工具分享
  • 2023美赛选题建议 美国大学生数学建模竞赛ABCDEF题
  • 2023,想跳槽的可以再等等