day36+day37 0-1背包
### 9.9 01背包问题(一维+二维)
背包问题分类:01背包(一种物品只有一个),完全背包(一种物品有无数个),多重背包(不同物品有不同数量)
46. 携带研究材料(第六期模拟笔试)
题目描述
小明是一位科学家,他需要参加一场重要的国际科学大会,以展示自己的最新研究成果。他需要带一些研究材料,但是他的行李箱空间有限。这些研究材料包括实验设备、文献资料和实验样本等等,它们各自占据不同的空间,并且具有不同的价值。
小明的行李空间为 N,问小明应该如何抉择,才能携带最大价值的研究材料,每种研究材料只能选择一次,并且只有选与不选两种选择,不能进行切割。
输入描述
第一行包含两个正整数,第一个整数 M 代表研究材料的种类,第二个正整数 N,代表小明的行李空间。
第二行包含 M 个正整数,代表每种研究材料的所占空间。
第三行包含 M 个正整数,代表每种研究材料的价值。
输出描述
输出一个整数,代表小明能够携带的研究材料的最大价值。
暴力解法:每个物品只有取和不取,用回溯算法枚举就可以。时间复杂度n2
01背包问题 二维
https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-1.html
https://www.bilibili.com/video/BV1cg411g7Y6
`dp[i][j]:i 来表示物品、j表示背包容量
`dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。
如:`dp[1][4] 表示什么意思呢?
任取物品0、物品1放入容量为4的背包中,最大价值是`dp[1][4]。
二维数组遍历顺序:先遍历物品,再遍历背包/先遍历背包,再遍历物品都可以。因为需要的值就是正上方和左上角的值。
遇到的问题:
非leetcode包装好的方法,需要获取数据
写的时候也有一些细节需要注意:
```java
import java.util.Scanner;
public class bag01TwoDimensional {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int bagCapacity = sc.nextInt();
int[] materialSpace = new int[num];
int[] materialValue = new int[num];
for (int i = 0; i < num; i++) {
materialSpace[i] = sc.nextInt();
}
for (int i = 0; i < num; i++) {
materialValue[i] = sc.nextInt();
}
//dp初始化
int[][] dp = new int[num][bagCapacity+1];
//初始化第一行:有简洁的写法,即直接从materialSpace[0]开始遍历。如果它大于包的容量,则不进入循环。
for (int i = materialSpace[0]; i <= bagCapacity; i++) {
dp[0][i] = materialValue[0];
}
//初始化第一列:其实不用写,默认的初始值就是0
for (int i = 1; i < num; i++) {
for (int j = 0; j <= bagCapacity; j++) {
// //不要第i个物品
// int noI = dp[i-1][j];
// //要第i个物品
// int withI = dp[i-1][j-materialSpace[i]] + materialValue[i];
if(materialSpace[i] > j){
dp[i][j] = dp[i-1][j];
}else{
dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-materialSpace[i]] + materialValue[i]);
}
}
}
// for (int i = 0; i < num; i++) {
// for (int j = 0; j <= bagCapacity; j++) {
// System.out.print("dp["+i+"]["+j+"] = "+ dp[i][j]+" ");
// }
// System.out.println();
// }
System.out.println(dp[num-1][bagCapacity]);
}
}
```
01背包问题 一维
https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-2.html
https://www.bilibili.com/video/BV1BU4y177kY
把矩阵压缩成一行,把上一层拷贝到下一层。滚动数组。
1.确定dp数组(dp table)以及下标的含义
dp`[j] :容量为j的背包能装进物品的最大价值。
2.确定递推公式
不放物品i:dp`[j]
放物品i:dp`[j-weight[i]]+value[i]
3.dp数组如何初始化(0/1确认很有讲究,很重要)
dp`[0] = 0;
4.确定遍历顺序
倒序遍历。如果正序遍历,会导致前面的物品被反复加入
5.打印dp数组(动态规划代码简短,直接看打印出来的dp数组是不是和自己设想的一致)
```java
public class bag02OneDimensional {
public static void main(String[] args) {
// int materialNum = 6;
// int capacity = 6;
//
// int[] weight = {2,2,3,1,5,2};
// int[] value = {2,3,1,5,4,3};
//get data
Scanner sc = new Scanner(System.in);
int materialNum = sc.nextInt();
int capacity = sc.nextInt();
int[] weight = new int[materialNum];
int[] value = new int[materialNum];
for (int i = 0; i < materialNum; i++) {
weight[i] = sc.nextInt();
}
for (int i = 0; i < materialNum; i++) {
value[i] = sc.nextInt();
}
int[] dp = new int[capacity+1];//当背包容量为i时,包内物品的最大价值为dp[i]
for (int i = 0; i < materialNum; i++) {
for (int j = capacity; j >= weight[i]; j--) {
int withoutI = dp[j];
int withI = dp[j-weight[i]] + value[i];
dp[j] = Math.max(withoutI,withI);
//System.out.println("dp["+i+"]["+j+"]"+" = " + dp[j]);
}
}
System.out.println(dp[capacity]);
}
}
```
### 9.10 416. Partition Equal Subset Sum
Given an integer array nums, return true if you can partition the array into two subsets such that the sum of the elements in both subsets is equal or false otherwise.
https://leetcode.cn/problems/partition-equal-subset-sum/description/
416. 分割等和子集
本题是 01背包的应用类题目
https://programmercarl.com/0416.%E5%88%86%E5%89%B2%E7%AD%89%E5%92%8C%E5%AD%90%E9%9B%86.html
https://www.bilibili.com/video/BV1rt4y1N7jE
01背包,里面的元素能不能刚好装满容量为数组元素和二分之一的背包。
物品的重量和价值相同
动态规划五部曲:
1.确定dp数组(dp table)以及下标的含义
dp`[j]:背包总容量为j,放进物品后,背的最大重量为dp[j]。
2.确定递推公式
3.dp数组如何初始化(0/1确认很有讲究,很重要)
4.确定遍历顺序
后序遍历
5.打印dp数组(动态规划代码简短,直接看打印出来的dp数组是不是和自己设想的一致)
自己做的时候错误点:
没有剪枝。当总和为奇数时,直接返回false即可。
```java
public class partitionEqualSubsetSum {
public boolean canPartition(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
if(sum%2 == 1) return false;
int target = sum/2;
int[] dp = new int[target + 1];
//先遍历物品,后遍历背包
for (int i = 0; i < nums.length; i++) {
for (int j = target; j >= nums[i]; j--) {
// int withI = dp[j - nums[i]] + nums[i];
// int withoutI = dp[j];
dp[j] = Math.max(dp[j - nums[i]] + nums[i],dp[j]);
}
}
return dp[target] == target;
}
}
class partitionEqualSubsetSumTest{
public static void main(String[] args) {
int[] nums = {1,2,3,5};
partitionEqualSubsetSum example = new partitionEqualSubsetSum();
System.out.println(example.canPartition(nums));
}
}
```
### 9.11 1049. Last Stone Weight II
You are given an array of integers stones where stones`[i] is the weight of the ith stone.
We are playing a game with the stones. On each turn, we choose any two stones and smash them together. Suppose the stones have weights x and y with x <= y. The result of this smash is:
If x == y, both stones are destroyed, and
If x != y, the stone of weight x is destroyed, and the stone of weight y has new weight y - x.
At the end of the game, there is at most one stone left.
Return the smallest possible weight of the left stone. If there are no stones left, return 0.
https://leetcode.cn/problems/last-stone-weight-ii/description/
1049. 最后一块石头的重量 II
本题就和 昨天的 416. 分割等和子集 很像了,可以尝试先自己思考做一做。
https://www.bilibili.com/video/BV14M411C7oV
https://programmercarl.com/1049.%E6%9C%80%E5%90%8E%E4%B8%80%E5%9D%97%E7%9F%B3%E5%A4%B4%E7%9A%84%E9%87%8D%E9%87%8FII.html
把石头尽量分成重量相近的两堆,比如总重量为23的石头堆分成11和12。
```java
public class lastStoneWeight2 {
public int lastStoneWeightII(int[] stones) {
int sum = 0;
for (int i = 0; i < stones.length; i++) {
sum += stones[i];
}
int target = sum/2;
int[] dp = new int[target+1];
for (int i = 0; i < stones.length; i++) {
//如果此时背包剩余容量小于待加入石头的重量,则没必要进入循环
//If the remaining capacity of the backpack at this time is less than the weight of the stones to be added, there is no need to enter the loop
for (int j = target; j >= stones[i]; j--) {
dp[j] = Math.max(dp[j],dp[j-stones[i]] + stones[i]);
}
}
//return Math.abs(dp[target]-(sum-dp[target]));
return sum - 2*dp[target];
}
}
class lastStoneWeight2Test{
public static void main(String[] args) {
lastStoneWeight2 example = new lastStoneWeight2();
int[] nums = {31,26,33,21,40};
System.out.println(example.lastStoneWeightII(nums));
}
}
```
### 9.12 494. Target Sum
You are given an integer array nums and an integer target.
You want to build an expression out of nums by adding one of the symbols '+' and '-' before each integer in nums and then concatenate all the integers.
For example, if `nums = [2, 1], you can add a '+' before 2 and a '-' before 1 and concatenate them to build the expression "+2-1".
Return the number of different expressions that you can build, which evaluates to target.
https://leetcode.cn/problems/target-sum/description/
494. 目标和
大家重点理解 递推公式:`dp[j] += dp[j - nums[i]],这个公式后面的提问 我们还会用到。
https://www.bilibili.com/video/BV1o8411j73x
https://programmercarl.com/0494.%E7%9B%AE%E6%A0%87%E5%92%8C.html
分成两个子集,加法在一个子集(left),减法在一个子集(right)。
sum = left + right ===> left = sum - right
target = left - right ===> left = target + right
===> 2left = sum + target
left = (sum+target)/2
如果不能整除,就是凑不成target,直接返回0
有多少种情况可以装满背包,就返回多少
nums = `[1,1,1,1,1], target = 3
dp`[j] : 装满容量为j的背包有dp[j] 种方法
背包里已有:
物品1: 有dp`[4] 种方法凑成dp[5];
物品2: 有dp`[3] 种方法凑成dp[5];
递推公式: `dp[j] += dp[j-num[i]];
初始化:`dp[0] = 1;
```java
public class targetSum {
public int findTargetSumWays(int[] nums, int target) {
int sum = 0;
for (int i : nums) {
sum += i;
}
//如果target的绝对值大于sum,那么无解
if ((sum + target) % 2 == 1 || Math.abs(target) > sum) return 0;
int capacity = (sum + target) >> 1;
int[] dp = new int[capacity + 1];
dp[0] = 1;
for (int i = 0; i < nums.length; i++) {
for (int j = capacity; j >= nums[i]; j--) {
dp[j] += dp[j-nums[i]];
}
}
return dp[capacity];
}
}
class targetSumTest {
public static void main(String[] args) {
targetSum example = new targetSum();
int[] nums = {1,1,1,1,1};
int target = 3;
System.out.println(example.findTargetSumWays(nums, target));
}
}
```
### 9.13 474. Ones and Zeroes
You are given an array of binary strings strs and two integers m and n.
Return the size of the largest subset of strs such that there are at most m 0's and n 1's in the subset.
A set x is a subset of a set y if all elements of x are also elements of y.
https://leetcode.cn/problems/ones-and-zeroes/description/
474.一和零
通过这道题目,大家先粗略了解, 01背包,完全背包,多重背包的区别,不过不用细扣,因为后面 对于 完全背包,多重背包 还有单独讲解。
https://www.bilibili.com/video/BV1rW4y1x7ZQ
https://programmercarl.com/0474.%E4%B8%80%E5%92%8C%E9%9B%B6.html
装满容器最多多少个物品?
m个0 n个1 凑成子集
背包:最多有m个0,n个1。装满这个背包最多有多少个物品?
dp`[i][j] 装满i个0,j个1的背包最多有dp[i][j]个物品
待加入物品有x个0,y个1
dp`[i][j] = Math.max((dp[i-x][j-y] + 1),dp[i][j])
初始化:
dp`[0][0] = 0;
非零坐标也初始化为0。防止递推公式求出的值被初始值覆盖。
```java
public class onesAndZero {
public int findMaxForm(String[] strs, int m, int n) {
int[][] dp = new int[m + 1][n + 1];
//iterate items first
for (String s : strs) {
int x = 0;
int y = 0;
//to get how many 0 and i in this element
char[] chars = s.toCharArray();
for (char c : chars) {
if (c == '0') {
x++;
} else {
y++;
}
}
//and then iterate the bag
for (int i = m; i >= x; i--) {
for (int j = n; j >= y; j--) {
dp[i][j] = Math.max((dp[i - x][j - y] + 1), dp[i][j]);
}
}
}
return dp[m][n];
}
}
class onesAndZeroTest {
public static void main(String[] args) {
onesAndZero example = new onesAndZero();
String[] strs = {"10","0","1"};
int m = 1;
int n = 1;
System.out.println(example.findMaxForm(strs,m,n));
}
}
```
相关文章:
day36+day37 0-1背包
### 9.9 01背包问题(一维二维) 背包问题分类:01背包(一种物品只有一个),完全背包(一种物品有无数个),多重背包(不同物品有不同数量) 46. 携带研究…...
PostMan使用变量
环境变量 使用场景 当测试过程中,我们需要对开发环境、测试环境、生产环境进行测试 不同的环境对应着不同的服务器,那么这个时候我们就可以使用环境变量来区分它们 避免切换测试环境后,需要大量的更改接口的url地址 全局变量 使用场景 当…...
多线程同步
多线程 程序中默认只有一个线程,pthread_create()函数调用后就有2个线程。 pthread_create() #include <pthread.h> #include <string.h> #include <unistd.h> #include <iostream> using namespace std; //线程函数 void * callback(vo…...
第159天:安全开发-Python-协议库爆破FTPSSHRedisSMTPMYSQL等
案例一: Python-文件传输爆破-ftplib 库操作 ftp 协议 开一个ftp 利用ftp正确登录与失败登录都会有不同的回显 使用ftplib库进行测试 from ftplib import FTP # FTP服务器地址 ftp_server 192.168.172.132 # FTP服务器端口(默认为21) ftp_po…...
软件测试 | APP测试 —— Appium 的环境搭建及工具安装教程
大家应该都有同一种感觉,学习appium最大的难处之一在于环境的安装,安装流程比较繁琐,安装的工具和步骤也较多,以下是基于Windows系统下的Android手机端的安装流程。就像我们在用Selenium进行web自动化测试的时候一样,我…...
计算机人工智能前沿进展-大语言模型方向-2024-09-13
计算机人工智能前沿进展-大语言模型方向-2024-09-13 1. OneEdit: A Neural-Symbolic Collaboratively Knowledge Editing System Authors: Ningyu Zhang, Zekun Xi, Yujie Luo, Peng Wang, Bozhong Tian, Yunzhi Yao, Jintian Zhang, Shumin Deng, Mengshu Sun, Lei Liang, Z…...
衡石分析平台使用手册-替换衡石minio
替换衡石minio 在使用HENGSHI SENSE服务过程中,可以根据业务需要替换HENGSHI自带的minio。本文讲述使用Aws S3和Aliyun OSS替代衡石minio的过程。 准备工作 在进行配置前,请在aws s3或aliyun oss完成如下准备工作。 创建access_key和secret_acces…...
怎么将几个pdf合成为一个?把几个PDF合并成为一个的8种方法
怎么将几个pdf合成为一个?将多个PDF文件合并成一个整体可以显著提高信息整合的效率,并简化文件的管理与传递。例如,将不同章节的电子书合成一本完整的书籍,或者将多个部门的报告整合成一个统一的文档,可以使处理流程变…...
明明没有程序占用端口,但是启动程序却提示端口无法使用,项目也启动失败
明明没有程序占用端口,但是启动程序却提示端口无法使用,项目也启动失败 win10、端口占用、port、netstat、used背景 曾在springboot中遇到过,新建spring cloud时又遇到这个问题,如果不从根本上解决,就需要改端口&…...
ClickHouse的安装配置+DBeaver远程连接
1、clickhouse的下载: 先去clickhouse官网进行下载,继续往下翻找文档,将DBeaver也下载下来 下载地址:https://packages.clickhouse.com/rpm/stable/ 下载这个四个rpm包 2、上传rmp文件到Linux中 自己创建的一个clickhouse-ins…...
UVM仿真的运行(四)—— objection 机制
目录 0. 引言 1. uvm_phase::execute_phase line 1432~1470 2. uvm_objection 2.1 get_objection_total 2.2 raise_objection 2.3 drop_objection 2.4 m_execute_scheduled_forks 2.5 wait_for 3. 小结 0. 引言 前面介绍了uvm仿真的启动,按照domain中指定的DAG的pha…...
【ShuQiHere】算法分析:揭开效率与复杂度的神秘面纱
【ShuQiHere】 🚀 引言 在计算机科学的世界中,算法 是每一个程序背后的隐形支柱。从简单的排序到复杂的人工智能,算法无处不在。然而,编写一个能运行的程序只是开始,当程序面对庞大的数据集时,算法的效率…...
记忆化搜索专题——算法简介力扣实战应用
目录 1、记忆化搜索算法简介 1.1 什么是记忆化搜索 1.2 如何实现记忆化搜索 1.3 记忆化搜索与动态规划的区别 2、算法应用【leetcode】 2.1 题一:斐波那契数 2.1.1 递归暴搜解法代码 2.1.2 记忆化搜索解法代码 2.1.3 动态规划解法代码 2.2 题二࿱…...
【Java】【力扣】83.删除排序链表中的重复元素
题目 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 示例 1: 输入:head [1,1,2] 输出:[1,2]示例 2: 输入:head [1,1,2,3,3] 输出&#…...
vue3项目实现全局国际化
本文主要梳理vue3项目实现全项目格式化,例如在我前面文章使用若依创建vue3的项目中,地址:若依搭建vue3项目在导航栏中切换,页面中所有的组件的默认语言随之切换,使用的组件库依旧是element-plus,搭配vue-i1…...
Oracle 19c异常恢复—ORA-01209/ORA-65088---惜分飞
由于raid卡bug故障,导致文件系统异常,从而使得数据库无法正常启动,客户找到我之前已经让多人分析,均未恢复成功,查看alert日志,发现他们恢复的时候尝试resetlogs库,然后报ORA-600 kcbzib_kcrsds_1错误 2024-09-15T17:07:32.55321508:00 alter database open resetlogs 2024-09-…...
【Webpack--000】了解Webpack
🤓😍Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-前端领域博主 🐱🐉若此文你认为写的不错,不要吝啬你的赞扬,求收藏,求评论,求一个大大的赞!👍* &#x…...
开源 AI 智能名片链动 2+1 模式 S2B2C 商城小程序与社交电商的崛起
摘要:本文深入探讨了社交电商迅速发展壮大的原因,并分析了开源 AI 智能名片链动 21 模式 S2B2C 商城小程序在社交电商中的重要作用。通过对传统电商与社交电商的对比,以及对各发展因素的剖析,阐述了该小程序如何为社交电商提供新的…...
在线IP代理检测:保护您的网络安全
在互联网飞速发展的今天,越来越多的人开始意识到网络安全和隐私保护的重要性。在线IP代理检测工具作为一种有效的网络安全手段,能够帮助用户识别和检测IP代理的使用情况,从而更好地保护个人隐私和数据安全。本文将详细介绍在线IP代理检测的相…...
【算法】BFS—解开密码锁的最少次数
题目 一个密码锁由 4 个环形拨轮组成,每个拨轮都有 10 个数字: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 。每个拨轮可以自由旋转:例如把 9 变为 0,0 变为 9 。每次旋转都只能旋转一个拨轮的一位数字。 锁的初始数字为 0000 ,一个…...
Stitches项目架构分析:RequireJS模块化设计与Grunt构建流程完全指南 [特殊字符]
Stitches项目架构分析:RequireJS模块化设计与Grunt构建流程完全指南 🚀 【免费下载链接】stitches HTML5 Sprite Sheet Generator 项目地址: https://gitcode.com/gh_mirrors/sti/stitches Stitches是一个基于HTML5的雪碧图生成器,它采…...
Buzz音频转录完全指南:3大核心功能+5个实战场景,快速掌握本地语音转文字技术
Buzz音频转录完全指南:3大核心功能5个实战场景,快速掌握本地语音转文字技术 【免费下载链接】buzz Buzz transcribes and translates audio offline on your personal computer. Powered by OpenAIs Whisper. 项目地址: https://gitcode.com/GitHub_Tr…...
隧道裂缝剥落病害AI识别系统
我国现有公路隧道超2.5万座,总里程超2.8万公里,其中运营超过15年的老旧隧道占比达35%。据交通运输部2025年统计,年均因隧道结构病害导致的交通中断超1200次,直接经济损失超45亿元。传统检测模式暴露四大核心痛点:检测周…...
PA100K数据集实战:从下载到结构化解析全流程
1. PA100K数据集初探:为什么选择它?如果你正在研究行人属性识别,PA100K绝对是个绕不开的宝藏数据集。这个数据集包含了10万张真实监控场景下的行人图像,每张图都标注了26种常见属性——从衣着风格(比如是否穿T恤、裙子…...
ARM指令追踪技术及TRCVICTLR寄存器详解
1. ARM指令追踪技术概述在嵌入式系统开发和调试过程中,指令追踪(Instruction Trace)是一项至关重要的技术。它通过硬件机制记录处理器的执行流程,为开发者提供程序运行的完整轨迹。ARM架构从v7开始引入嵌入式跟踪宏单元࿰…...
从电磁炉到户外电源:拆解单相SVPWM如何让你的逆变器更安静、更高效
从电磁炉到户外电源:单相SVPWM如何实现静音与高效的双重突破当你深夜用电磁炉煮面时,是否曾被突然的蜂鸣声吓一跳?或是发现户外电源给设备充电时,散热风扇的噪音盖过了山林鸟鸣?这些常见问题背后,隐藏着一个…...
Scroll Reverser:让Mac的多设备滚动体验回归直觉的免费神器
Scroll Reverser:让Mac的多设备滚动体验回归直觉的免费神器 【免费下载链接】Scroll-Reverser Per-device scrolling prefs on macOS. 项目地址: https://gitcode.com/gh_mirrors/sc/Scroll-Reverser 你是否曾经在MacBook的触控板和鼠标之间切换时࿰…...
可解释AI新突破:基于局部帕累托最优的模型解释框架
1. 项目概述:当AI模型成为“黑箱”,我们如何撬开它?在机器学习项目里摸爬滚打十几年,我见过太多这样的场景:团队花大力气训练出一个准确率高达95%的复杂模型(比如深度神经网络),业务…...
如何快速解锁艾尔登法环帧率限制:终极性能优化指南
如何快速解锁艾尔登法环帧率限制:终极性能优化指南 【免费下载链接】EldenRingFpsUnlockAndMore A small utility to remove frame rate limit, change FOV, add widescreen support and more for Elden Ring 项目地址: https://gitcode.com/gh_mirrors/el/EldenR…...
Performance-Fish:让你的《环世界》后期游戏帧率提升400%的终极优化方案
Performance-Fish:让你的《环世界》后期游戏帧率提升400%的终极优化方案 【免费下载链接】Performance-Fish Performance Mod for RimWorld 项目地址: https://gitcode.com/gh_mirrors/pe/Performance-Fish 你是否曾在《环世界》游戏后期,面对庞大…...
