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

代码随想录算法训练营第46期Day37,38,39,41

这几天晚上看比赛,就把刷题耽误了。还好是开新章节,前面的题都比较简单。

然后周天做完了又忘记发了

动态规划

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数

 Day37前两道题太简单了,我们从第三道题开始

leetcode.746.使用最小花费爬楼梯

class Solution {
public:int minCostClimbingStairs(vector<int>& cost) {vector<int> dp(cost.size()+8);//dp数组存储当前点位的最优解dp[0]=0;dp[1]=0;for(int i=2;i<=cost.size();i++){dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);//这是dp公式,到达第i阶的最优解肯定是i-1阶的最优解+从i-1的花费和i-2阶的最有解+从i-2阶段的花费中小的那一个}return dp[cost.size()];}};

leetcode.62.不同路径

class Solution {
public:int uniquePaths(int m, int n) {int dp[105][105];dp[0][0]=0;for(int i=1;i<=m;i++){dp[i][1]=1;}for(int i=1;i<=n;i++){dp[1][i]=1;}for(int i=2;i<=m;i++){for(int j=2;j<=n;j++){dp[i][j]=dp[i][j-1]+dp[i-1][j];}}return dp[m][n];}
};

leetcode.63.不同路径Ⅱ

class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size();int n = obstacleGrid[0].size();vector<vector<int>> dp(m, vector<int>(n, 0));//注意最好用vector容器。都初始化为0/*if(obstacleGrid[0][0]==1||obstacleGrid[m-1][n-1]==1){//如果开始或终点有障碍那直接返回障碍return 0;}*/for(int i=0;i<m;i++){if(obstacleGrid[i][0]==1){//如果在边界的两条线上有障碍,那从障碍开始一下路径数都为0break;}dp[i][0]=1;}for(int i=0;i<n;i++){ if(obstacleGrid[0][i]==1){break;}dp[0][i]=1;}for(int i=1;i<m;i++){for(int j=1;j<n;j++){if(obstacleGrid[i][j]==0)dp[i][j]=dp[i][j-1]+dp[i-1][j];//如果碰不到障碍就进行dp,保证障碍处路径为0}}return dp[m-1][n-1];}
};

leetcode.416.分割等和子集

class Solution {
public:bool canPartition(vector<int>& nums) {sort(nums.begin(),nums.end());int sum=0;for(int i=0;i<nums.size();i++){sum+=nums[i];}vector<int> dp(11111,0);//这里数组尽量开大点,不然过不了if (sum % 2 == 1) return false;sum= sum / 2;//能够分成两个子集的元素和相等说明,有一部分元素相加的和是总和的一半//那么元素个数是种类,sum/2是容量的01背包问题就出现了for(int i=0;i<nums.size();i++){for(int j=sum;j>=nums[i];j--){dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);}}if(dp[sum]==sum){return true;}return false;}
};

leetcode.1049.最后一块的石头重量

class Solution {
public:
//和分割等和子列类似int lastStoneWeightII(vector<int>& stones) {vector<int> dp(10010,0);int sum=0;for(int i=0;i<stones.size();i++){sum+=stones[i];}int sum1=sum;sum=sum/2;for(int i=0;i<stones.size();i++){for(int j=sum;j>=stones[i];j--){dp[j]=max(dp[j],dp[j-stones[i]]+stones[i]);}}return sum1-2*dp[sum];}
};

leetcode.494.目标和

假设加法的总和为x,那么减法对应的总和就是sum - x。

所以我们要求的是 x - (sum - x) = target

x = (target + sum) / 2

此时问题就转化为,用nums装满容量为x的背包,有几种方法

  • 不放物品i:即背包容量为j,里面不放物品i,装满有dp[i - 1][j]中方法。

  • 放物品i: 即:先空出物品i的容量,背包容量为(j - 物品i容量),放满背包有 dp[i - 1][j - 物品i容量] 种方法。

  • if (nums[i] > j) dp[i][j] = dp[i - 1][j]; //说明背包容量装不下 物品i,所以此时装满背包的方法值 等于 不放物品i的装满背包的方法,

  1. 举例推导dp数组

输入:nums: [1, 1, 1, 1, 1], target: 3

bagSize = (target + sum) / 2 = (3 + 5) / 2 = 4

dp数组状态变化如下

那么最上行dp[0][j] 如何初始化呢?

dp[0][j]:只放物品0, 把容量为j的背包填满有几种方法。

只有背包容量为 物品0 的容量的时候,方法为1,正好装满。

其他情况下,要不是装不满,要不是装不下。

所以初始化:dp[0][nums[0]] = 1 ,其他均为0 。

表格最左列也要初始化,dp[i][0] : 背包容量为0, 放物品0 到 物品i,装满有几种方法。

都是有一种方法,就是放0件物品。

即 dp[i][0] = 1

如果有两个物品,物品0为0, 物品1为0,装满背包容量为0的方法有几种。

  • 放0件物品
  • 放物品0
  • 放物品1
  • 放物品0 和 物品1

此时是有4种方法。

其实就是算数组里有t个0,然后按照组合数量求,即 2^t 

遍历顺序

在明确递推方向时,我们知道 当前值 是由上方和左上方推出。

那么我们的遍历顺序一定是 从上到下,从左到右。

因为只有这样,我们才能基于之前的数值做推导。

 for (int i = 0; i < nums.size(); i++) {if (nums[i] == 0) numZero++;dp[i][0] = (int) pow(2.0, numZero);}
class Solution {
public:
int count=0;int findTargetSumWays(vector<int>& nums, int target) {int sum=0;for(int i=0;i<nums.size();i++){sum+=nums[i];  }if (abs(target) > sum) return 0; sum+=target;if(sum%2==1){return 0;}       sum=sum/2;int bagSize=sum;vector<vector<int>> dp(nums.size(), vector<int>(10010, 0));// 初始化最上行if (nums[0] <= bagSize) dp[0][nums[0]] = 1; // 初始化最左列,最左列其他数值在递推公式中就完成了赋值dp[0][0] = 1; int numZero = 0;for (int i = 0; i < nums.size(); i++) {if (nums[i] == 0) numZero++;dp[i][0] = (int) pow(2.0, numZero);}// 以下遍历顺序行列可以颠倒for (int i = 1; i < nums.size(); i++) { // 行,遍历物品for (int j = 0; j <= bagSize; j++) { // 列,遍历背包if (nums[i] > j) dp[i][j] = dp[i - 1][j]; else dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i]];}}return dp[nums.size() - 1][bagSize];}
};

一维数组版

二维DP数组递推公式: dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i]];

去掉维度i 之后,递推公式:dp[j] = dp[j] + dp[j - nums[i]] ,即:dp[j] += dp[j - nums[i]]

遍历物品放在外循环,遍历背包在内循环,且内循环倒序(为了保证物品只使用一次)。

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int sum = 0;for (int i = 0; i < nums.size(); i++) sum += nums[i];if (abs(target) > sum) return 0; // 此时没有方案if ((target + sum) % 2 == 1) return 0; // 此时没有方案int bagSize = (target + sum) / 2;vector<int> dp(bagSize + 1, 0);dp[0] = 1;for (int i = 0; i < nums.size(); i++) {for (int j = bagSize; j >= nums[i]; j--) {dp[j] += dp[j - nums[i]];}}return dp[bagSize];}
};

深搜遍历做法

class Solution {
public:
int count=0;void backtrack(vector<int>& nums,int target,int index,int sum){if(index==nums.size()){if(sum==target){count++;}}else{backtrack(nums,target,index+1,sum+nums[index]);backtrack(nums,target,index+1,sum-nums[index]);}}int findTargetSumWays(vector<int>& nums, int target) {backtrack(nums,target,0,0);return count;  }
};

leetcode.474.一零和..

本题中strs 数组里的元素就是物品,每个物品都是一个!

而m 和 n相当于是一个背包,两个维度的背包

理解成多重背包的同学主要是把m和n混淆为物品了,感觉这是不同数量的物品,所以以为是多重背包。

但本题其实是01背包问题!

只不过这个背包有两个维度,一个是m 一个是n,而不同长度的字符串就是不同大小的待装物品。

开始动规五部曲:

  1. 确定dp数组(dp table)以及下标的含义

dp[i][j]:最多有i个0和j个1的strs的最大子集的大小为dp[i][j]

  1. 确定递推公式

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背包! 只不过物品的重量有了两个维度而已。

  1. dp数组如何初始化

01背包的dp数组初始化为0就可以。

因为物品价值不会是负数,初始为0,保证递推的时候dp[i][j]不会被初始值覆盖。

  1. 确定遍历顺序

01背包一定是外层for循环遍历物品,内层for循环遍历背包容量

那么本题也是,物品就是strs里的字符串,背包容量就是题目描述中的m和n。(相当于之前的一维dp,采用了滚动数组)

倒序遍历是为了保证物品i只被放入一次!。但如果一旦正序遍历了,那么物品0就会被重复加入多次!

那么问题又来了,为什么二维dp数组遍历的时候不用倒序呢?

因为对于二维dp,dp[i][j]都是通过上一层即dp[i - 1][j]计算而来,本层的dp[i][j]并不会被覆盖!

class Solution {
public:int findMaxForm(vector<string>& strs, int m, int n) {vector<vector<int>> dp(m + 1, vector<int> (n + 1, 0)); // 默认初始化0for (string str : strs) { // 遍历物品int oneNum = 0, zeroNum = 0;for (char c : str) {if (c == '0') zeroNum++;else oneNum++;}for (int i = m; i >= zeroNum; i--) { // 遍历背包容量且从后向前遍历!for (int j = n; j >= oneNum; j--) {dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);}}}return dp[m][n];}
};

相关文章:

代码随想录算法训练营第46期Day37,38,39,41

这几天晚上看比赛&#xff0c;就把刷题耽误了。还好是开新章节&#xff0c;前面的题都比较简单。 然后周天做完了又忘记发了 动态规划 确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数 Day37前两道题太简单…...

点跟踪论文—RAFT: Recurrent All-Pairs Field Transforms for Optical Flow-递归的全对场光流变换

点目标跟踪论文—RAFT: Recurrent All-Pairs Field Transforms for Optical Flow-递归的全对场光流变换 读论文RAFT密集光流跟踪的笔记 RAFT是一种新的光流深度网络结构&#xff0c;由于需要基于点去做目标的跟踪&#xff0c;因此也是阅读了像素级别跟踪的一篇ECCV 2020的经典…...

jmeter学习(6)逻辑控制器-循环

循环执行 1、循环读取csv文件的值 2、foreach 读取变量&#xff0c;变量数字后缀有序递增&#xff0c;通过counter实现 ${__V(typeId${typeIdNum})} beansell断言 String typeIdNum vars.get("typeIdNum"); String response prev.getResponseDataAsString(); …...

unity学习笔记-安装与部署

unity学习笔记-安装与部署 unity & visual studio下载unityvisual studio 创建工程项目内的布局介绍初始化项目各目录介绍1. 场景视图&#xff08;Scene&#xff09;2. 游戏视图&#xff08;Game&#xff09;3. 层次结构视图&#xff08;Hierarchy&#xff09;4. 检查器视图…...

Django+MySQL接口开发完全指南

前言 本文将详细介绍如何使用Django结合MySQL数据库开发RESTful API接口。我们将从环境搭建开始&#xff0c;一步步实现一个完整的接口项目。 环境准备 首先需要安装以下组件&#xff1a; Python 3.8Django 4.2MySQL 8.0mysqlclientdjangorestframework 安装命令 # 创建虚…...

CentOS7上下载安装 Docker Compose

Docker Compose简要介绍&#xff08;想直接看安装步骤的请跳转到[必要的安装步骤]&#xff09; Docker Compose 是一个用于定义和管理多容器 Docker 应用的工具&#xff0c;它可以通过一个简单的 YAML 文件&#xff08;docker-compose.yml&#xff09;来配置应用程序的服务、网…...

虚拟机的 NAT 模式 或 Bridged 模式能够被外界IPping通

如果虚拟机使用的是 NAT 模式 或 Bridged 模式&#xff0c;通常可以让外部网络&#xff08;例如互联网&#xff09;访问虚拟机。NAT 和 Bridged 模式的不同之处在于它们如何将虚拟机连接到宿主机和外部网络。以下是这两种模式的详细说明&#xff1a; 1. NAT 模式 在 NAT 模式…...

C# 使用Dll的几种方法举例

使用 DLL&#xff08;动态链接库&#xff09;是 C# 开发中常见的任务之一。DLL 文件包含可以在运行时加载的代码和数据&#xff0c;允许程序共享功能和资源&#xff0c;降低程序的内存占用并促进代码的复用。本篇文章将深入探讨 C# 中使用 DLL 的多种方法&#xff0c;并提供相关…...

什么是不同类型的微服务测试?

大家好&#xff0c;我是锋哥。今天分享关于【什么是不同类型的微服务测试&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; 什么是不同类型的微服务测试&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 微服务架构中的测试可以分为多种类…...

Docker 拉取镜像时配置可用镜像源(包含国内可用镜像源)

在/etc/docker/daemon.json中写入如下内容(如果文件不存在请新建该文件)&#xff1a; { "registry-mirrors":["https://registry.docker-cn.com"] } 重新加载 json 配置文件&#xff1a; sudo systemctl daemon-reload重启 docker 服务&#xff1a; sud…...

International Symposium on Artificial Intelligence Innovations

计算机科学&#xff08;Computer Science&#xff09;&#xff1a; 算法、自动化软件工程、生物信息学和科学计算、计算机辅助设计、计算机动画、计算机体系结构、计算机建模、计算机网络、计算机安全、计算机图形学与图像处理、数据库与数据挖掘、数据压缩、数据加密、数字信号…...

Golang笔记_day10

Go面试题&#xff08;三&#xff09; 1、什么是channel&#xff0c;为什么它可以做到线程安全 在Go语言中&#xff0c;channel是一种类型&#xff0c;它可以用来在协程之间传递数据通过共享内存来通信&#xff1a; 通过共享内存来通信是指多个线程或进程直接访问相同的内存区域…...

mlir learn

https://github.com/j2kun/mlir-tutorial 学习这个项目 https://www.jeremykun.com/2023/08/10/mlir-getting-started/ get start 用我的mac编译一下试试看 然后遇到架构不对的问题 因为他的提交默认是x86 https://github.com/j2kun/mlir-tutorial/pull/1/commits/5a267e269d57…...

Windows安装RabbitMQ 4.0.2(图文教程)

本章教程,主要记录在Windows 10上RabbitMQ 4.0.2的安装过程。 一、下载安装包 1、官方下载(速度不稳定) Erlang:https://github.com/erlang/otp/releases/download/OTP-26.0/otp_win64_26.0.exe RabbitMQ 4.0.2:https://github.com/rabbitmq/rabbitmq-server/releases/do…...

分布式系统中为什么需要使用消息队列

本文转载自 linkedkeeper.com 消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能&#xff0c;成为异步RPC的主要手段之一。 当今市面上有很多主流的消息中间件&#xff0c;如老牌的ActiveMQ、RabbitMQ&#…...

Linux环境配置(学生适用)

1.挑选最便宜的云服务器 如腾讯云服务器&#xff0c;华为云服务器&#xff0c;百度云服务器等等…… 2.找到你的云服务器实例&#xff0c;然后找到你的公网IP。 3.云服务器实例 ---更多 --- 重置root密码 (一定要重置&#xff09; 4. 下载并安装 xshell 或者其他登陆软件 xshel…...

麦禾软件:Mac用户找免费开源工具的最佳选择

抖知书老师推荐&#xff1a; ​麦禾软件已经成为众多Mac用户的必备平台&#xff0c;尤其对于那些经常寻找免费、开源、正版软件的用户来说&#xff0c;绝对是一个福音。随着科技的不断进步和用户需求的提升&#xff0c;安全、便捷的软件下载体验成为用户选择平台的核心标准。而…...

OpenCV4.8 开发实战系列专栏之 08 - 通道分离与合并

大家好&#xff0c;欢迎大家学习OpenCV4.8 开发实战专栏&#xff0c;长期更新&#xff0c;不断分享源码。 专栏代码全部基于C 与Python双语演示&#xff0c;专栏答疑群 请联系微信 OpenCVXueTang_Asst 本文关键知识点&#xff1a; OpenCV中默认imread函数加载图像文件&#…...

iOS 18.1 RC 版本发布,修复iPhone16随机重启、浏览视频卡顿等bug

今日&#xff0c;苹果发布 iOS 18.1 RC 版本升级&#xff0c;内部版本号为 22B82。 iOS 18.1 RC 也就是 iOS 18.1 准正式版&#xff0c;如果没有大的 Bug&#xff0c;这将是 iOS 18.1 正式版发布前最后一次更新&#xff0c;正式版预计下周向消费者推送。 该 RC 版除了为海外用…...

安装buildkit,并使用buildkit构建containerd镜像

背景 因为K8s抛弃Docker了,所以就只装了个containerd,这样就需要一个单独的镜像构建工具了,就用了buildkit,这也是Docker公司扶持的,他们公司的人出来搞的开源工具,官网在 https://github.com/moby/buildkit 简介 服务端为buildkitd,负责和runc或containerd后端连接干活,目前…...

maven jar包二进制文件 invalid stream header: EFBFBDEF 的错误

背景&#xff1a; 将jasper模板文件导入jar包后&#xff0c;生成文件报错 org.springframework.core.io.Resource resource new ClassPathResource("/template/XXXX.jasper");jasperPrint JasperFillManager.fillReport(resource.getInputStream(), paramentMap, …...

Git绑定Gitee或Github以及Git面试常见题

1.绑定Git或Gitee Git绑定Gitee或GitHub的过程相对简单&#xff0c;以下是详细的步骤说明&#xff1a; 一、绑定Gitee仓库 在Gitee上创建仓库 登录Gitee官网&#xff0c;点击首页右上角的“”号&#xff0c;选择“新建仓库”。在新建仓库页面&#xff0c;输入仓库的名称、描述…...

值得细读的8个视觉大模型生成式预训练方法

写在前面 大语言模型的进展催生出了ChatGPT这样的应用&#xff0c;让大家对“第四次工业革命”和“AGI”的来临有了一些期待&#xff0c;也作为部分原因共同造就了美股2023年的繁荣。LLM和视觉的结合也越来越多&#xff1a;比如把LLM作为一种通用的接口&#xff0c;把视觉特征…...

go 包相关知识

在Go语言中&#xff0c;包的引用和搜索路径是由环境变量GOPATH和GO111MODULE共同决定的。 GOPATH环境变量&#xff1a;这个变量定义了默认的工作目录&#xff0c;Go命令行工具将会在这个目录下查找包文件。这个目录通常包含三个子目录&#xff1a;src、bin和pkg。 src目录包含…...

机器学习:opencv--人脸检测以及微笑检测

目录 前言 一、人脸检测的原理 1.特征提取 2.分类器 二、代码实现 1.图片预处理 2.加载分类器 3.进行人脸识别 4.标注人脸及显示 三、微笑检测 前言 人脸检测是计算机视觉中的一个重要任务&#xff0c;旨在自动识别图像或视频中的人脸。它可以用于多种应用&#xff0…...

linux系统挂载硬盘

参考链接&#xff1a;https://www.cnblogs.com/wenhainan/p/12292823.html &#xff08;1&#xff09;lsblk命令查看磁盘挂载情况 &#xff08;2&#xff09;使用fdisk分区新磁盘 如果要分多个分区需指定每个分区的大小 &#xff08;3&#xff09;格式化新分区 mkfs命令格…...

MySQL实现主从同步

一、首先我们准备3台mysql 分别为&#xff1a; 主服务器&#xff1a;test-mysql-master,端口3306 从服务器&#xff1a;test-mysql-slave1,端口3307 从服务器&#xff1a;test-mysql-slave2,端口3308 注意&#xff1a;如果防火墙是开着的记得把关掉&#xff0c;并且重启docker…...

人工智能--数学基础

目录 ​编辑2.1 线性代数基础 2.2 微积分及优化理论 2.3 概率论与统计学 2.4 信息论简介 2.1 线性代数基础 线性代数是处理向量空间&#xff08;包括有限维或无限维&#xff09;以及这些空间上的线性映射的一门数学分支。在线性代数中&#xff0c;最核心的概念包括向量、矩…...

2024人工智能技术的普及 如何看待AI技术的应用前景

AI 技术的应用前景十分广阔&#xff0c;但也面临着一些挑战&#xff0c;以下是对其应用前景的一些看法&#xff1a; 积极方面&#xff1a; 多行业深度融合与效率提升5&#xff1a; 医疗领域&#xff1a;AI 在医疗影像分析、辅助诊断、疾病预测等方面具有巨大潜力。例如&#xf…...

日常记录:springboot 2.2.5 + es 6.8.12

前言 最近有用到搜索引擎的功能&#xff0c;这不得把之前的es过程实践一遍&#xff0c;但发现过程坎坷&#xff0c;因为版本太低了。 一、安装es 6.8.12 安装过程跟之前写那章日常记录&#xff1a;elasticsearch 在linux安装_elasticsearch linux安装-CSDN博客一样&#xff0…...