算法刷题-动态规划-1

算法刷题-动态规划-1

  • 不同路径
  • 不同路径||
    • 方法一:
    • 方法二
  • 第N个泰波那契数
    • 递归写法
    • 滚动数组
  • 三步问题
    • 递归操作
    • 滚动数组
  • 使用最小画法爬楼梯
    • 递归
  • 解码方法
    • 方法一
    • 方法二:(大佬讲解)

不同路径

在这里插入图片描述
在这里插入图片描述

//机器人不同的路径进入到指定的地点
public static int uniquepath(int m, int n) {if (m <= 0 || n <= 0){return 0;}int[][] dp = new int[m][n];//初始化//如果只有i,j中有一个为0,那么机器人行走的方向只能有一种方式for (int i = 0; i < m; i++){dp[i][0] = 1;}for (itn i = 0; i < n; i++)  {dp[0][i] = 1;  }//推导出dp[m-1][n-1],因为定义dp[i][j]就是表示的是在[i][j]点  //不同的路径的数目  for (itn i = 1; i < m; i++)    {for (int j = 1; j < n; j++)    {dp[i][j] = dp[i - 1][j] + dp[i][j - 1];    }}return dp[m - 1][n - 1];    }

不同路径||

在这里插入图片描述

在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/55c59dbc1da64e20aed014ff76118002.png)

方法一:

大佬讲解
在这里插入图片描述

class Solution {
public:/*** 1. 确定dp数组下标含义 dp[i][j] 从(0,0)到(i,j)可能的路径种类;* 2. 递推公式 dp[i][j] = dp[i-1][j] + dp[i][j-1] 但是需要加限制条件就是没有障碍物的时候*    if(obstacleGrid[i][j] == 0) dp[i][j] = dp[i-1][j] + dp[i][j-1];* 3. 初始化 当obstacleGrid[i][j] == 0时,dp[i][0]=1 dp[0][i]=1 初始化横竖就可;* 4. 遍历顺序 一行一行遍历;* 5. 推导结果;*/int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {/* 计算数组大小 */int m = obstacleGrid.size();int n = obstacleGrid[0].size();/* 定义dp数组 */vector<vector<int>> dp(m,vector<int>(n,0));/* 初始化dp数组 */for(int i = 0; i < m && obstacleGrid[i][0] == 0; i++)dp[i][0] = 1; for(int i = 0; i < n && obstacleGrid[0][i] == 0; i++)   dp[0][i] = 1;      /* 一行一行遍历 */     for(int i = 1; i < m; i++) {     for(int j = 1; j < n; j++) {     /* 去除障碍物 */     if(obstacleGrid[i][j] == 1) continue;     dp[i][j] = dp[i-1][j] + dp[i][j-1];     }}return dp[m-1][n-1];     }
};

方法二

多加一行和一列的虚拟节点,防止出现越界的情况,
把它们初始化成0,但是要保证第一个节点初始化成1.
dp[0][1] = 1;


class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int m = obstacleGrid.size(), n = obstacleGrid[0].size();vector<vector<int>> dp(m + 1, vector<int>(n + 1));dp[0][1] = 1;for(int i = 1; i <= m; i++) {for(int j = 1; j <= n; j++) {if(obstacleGrid[i - 1][j - 1] == 1) continue;else dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}return dp[m][n];}

第N个泰波那契数

在这里插入图片描述


递归写法

1。先确定函数的一定是什么dp[ i ] 表示:第 i 个泰波那契数
2。题目中的关系代数是 dp[ i ] = dp[ i - 1 ] + dp[ i - 2 ] + dp[ i - 3。边界是T(0)=0,T(1)=1,T(2)=1T(0)=0, T(1)=1,
4。初始化为dp[ 0 ] = 0,dp[ 1 ] = 1,dp[ 2 ] = 1

class Solution {
public:int tribonacci(int n) {vector<int> dp(n + 1);if (n == 0) {return 0;   }if (n <= 2)   {return 1;   }dp[0] = 0, dp[1] = 1, dp[2] = 1;   for (int i = 3; i <= n; i++) {   dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];   }return dp[n];   }
};

滚动数组

class Solution {
public:int tribonacci(int n) {if (n == 0) {return 0;}if (n <= 2) {  return 1;  }int p = 0, q = 0, r = 1, s = 1;  for (int i = 3; i <= n; ++i) {  p = q;  q = r;  r = s;  s = p + q + r;  }return s;  }
};

三步问题

在这里插入图片描述

这就是老油条的步骤了,
先确定自己定义的函数,然后找出关系式,然后确定初始值

递归操作

class Solution {  
public:  int waysToStep(int n) {  vector<in#t> dp(n + 1);  const int MOD = 1e9 + 7;  //边界问题    if (n == 1 || n == 2) return n;    if (n == 3) return 4;    //初始化定义    dp[1] = 1, dp[2] = 2, dp[3] = 4;    for (int i = 4; i <= n; i++) {   dp[i] = ((dp[i - 3] + dp[i - 2]) % MOD + dp[i - 1]) % MOD;   }return dp[n];   }
};

滚动数组

class Solution {    
public:    int waysToStep(int n) {     int a=1,b=2,c=4,i;     for(i=2;i<=n;i++){     long long t=(a+b)%1000000007;     t=(t+c)%1000000007;     a=b;     b=c;     c=t;     }return a;     }
};

使用最小画法爬楼梯

在这里插入图片描述
在这里插入图片描述

题目要求的是到达第n级台阶楼层顶部的最小花费,可以用动态规划来解,下面一步一步来讲怎样确定状态空间、怎样给出状态转移方程。

递归

  1. 大佬讲解

  2. 最近的一步有两种情况,

  3. 从 dp[ i - 1 ] 走一步过来,支付cost[ i - 1 ] 的费用; 1. 从 dp[ i - 1 ] 走一步过来,支付cost[ i - 1 ] 的费用;

  4. 从 dp[ i - 2 ] 走两步过来,支付cost[ i - 2 ] 的费用。
    而 dp[ i ] 就是到达 i 位置的最小花费,
    那我们就能得出状态转移方程:
    dp [ i ] = min( dp[ i - 1 ] + cost[ i - 1 ],dp[ i - 2 ] + cost[ i - 2 ] )


class Solution {  
public:  int minCostClimbingStairs(vector<int>& cost) {  int n = cost.size();  // 创建dp表,这样初始化默认填充的是 0   vector<int> dp(n + 1);  for (int i = 2; i <= n; i++) {  dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);  }return dp[n];  }
};

解码方法

在这里插入图片描述

在这里插入图片描述

方法一

动态规划的使用:
1。确立dp 数组的定义,代表的是 dp[i] 位置代表的是第i个位置时候解码方法的总数。
2。找关系代数=

  1. s[ i ] 单独解码,如果是单独解码,当 s[ i ] 的值是 1~9 的时候可以自己解码,
    自己解码的方案数就是 dp[ i - 1 ],如果 s[ i ] 的值是 0,那方案数就是0,整体解码失败,

  2. s[ i ] 和 s[ i - 1 ] 一起解码,当 s[ i - 1 ] * 10 + s[ i ] 的值是 10~26 的时候就可以解码,
    而解码数就是 dp[ i - 2 ],如果解码失败,不在这个区间内,那方案数就也是0。
    3。初始化dp数组,
    初始化 dp[ 0 ] 和 dp[ 1 ] 位置,
    dp[ 0 ] 位置,如果s[ 0 ] 解码成功就是1,不成功就是0
    dp[ 1 ] 位置,如果 dp[ 1 ] 能自己解码,就 + 1,如果能跟 dp[ 0 ] 一起解码,就再 + 1,
    如果dp[ 1 ] 两种情况都不能解码,就是0。(所以可能是0, 1, 2)

class Solution {
public:int numDecodings(string s) {int n = s.size();vector<int> dp(size);dp[0] = s[0] != '0';if (size == 1) return dp[0];if (s[0] != '0' && s[1] != '0') dp[1]++;int t = (s[0] - '0') * 10 + (s[1] - '0');if (t >= 10 && t <= 26) dp[1]++;for (int i = 2; i < size; i++) {if (s[i] != '0') dp[i] += dp[i - 1]; t = (s[i - 1] - '0') * 10 + (s[i] - '0');if (t >= 10 && t <= 26) dp[i] += dp[i - 2]; //一起解码}return dp[n - 1];}
};

方法二:(大佬讲解)

在这里插入图片描述

class Solution {
public:int numDecodings(string s) {if (s[0] == '0') return 0;int n = s.size();vector<int> dp(n + 1, 1);//dp[0]表示s[-1]的状态, dp[1] 表示 s[0]的状态//dp[i] 表示 s[i-1]的状态for (int i = 2; i <= n; i++) {if (s[i - 1] == '0') {if (s[i - 2] == '1' || s[i - 2] == '2')//唯一译码,不增加情况dp[i] = dp[i - 2]; else//这里要好好理解一下,比如给定340, 输出可行的编码数为0, 因为0和40都无法转换  return 0;  }else if (s[i - 2] == '1' || s[i - 2] == '2' && s[i - 1] >= '1' && s[i - 1] <= '6')dp[i] = dp[i - 1] + dp[i - 2];  else//当上述条件都不满足,维持上一个状态  dp[i] = dp[i - 1];  }//for(auto c:dp) cout << c << ",";  return dp[n];//返回dp[n] 即最后 s[n-1] 的状态  }
};

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

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

相关文章

【无标题】dp80采集机和机器人通信相关框架总结

采血机器人通信解析相关框架总结: 类似于dp80,将整个过程进行了分解如下: 类似于dp80,将整个过程进行了分解如下: 上位机界面在进行点击操作的时候,先是通信协议的解析,解析后改变采血的控制状态如下: Dp80主要框架解析࿱

现代计算与光学的跨界机遇——

时至今日&#xff0c;互补氧化金属半导体&#xff08;CMOS&#xff09;技术的飞速发展促进了集成电路的空前成功。 晶体管的创新与时俱进 正如戈登-E-摩尔&#xff08;Gordon E. Moors&#xff09;在1965年预测的那样&#xff0c;每隔18-24个月&#xff0c;计算芯片上的晶体管数…

如何保持口腔健康?羊大师全面指南!

口腔健康对于我们的整体健康至关重要。保持口腔健康可以帮助我们避免口腔疾病&#xff0c;如龋齿、牙周疾病等。口腔健康与身体其他部分的健康也有很大的关系。我们应该如何保持口腔健康呢&#xff1f;在本文中&#xff0c;小编羊大师将为您提供全面指南&#xff0c;详细介绍如…

回归算法优化过程推导

假设存在一个数据集&#xff0c;包含工资、年龄及贷款额度三个维度的数据。我们需要根据这个数据集进行建模&#xff0c;从而在给定工资和年龄的情况下&#xff0c;实现对贷款额度的预测。其中&#xff0c;工资和年龄是模型构建时的两个特征&#xff0c;额度是模型输出的目标值…

MySQL数据库常见错误及解决方案

“时记数据安全,共享优质资源”,数据库安全是指数据库数据的完整、真实、可靠和可用性。数据库也是一种软件系统,与其他软件系统一样也需要保护,需要采取一定的技术和一定的安全管理策略,保证数据库中的数据不被泄漏、不被破坏、不被修改或删除。本文列举MySQL数据库常见错…

RH850 G3KH异常处理简述

目录 1.概述 2.异常处理后现场恢复 3.异常处理地址识别 4.小结 1.概述 我们首先来看&#xff0c;G3KH的关键寄存器&#xff0c;PSW PSW--Program status word PSW寄存器里有表征程序状态的flag&#xff0c;CPU操作状态的flag。如下 UM---是否是user mode&#xff1b;0--…

3D打印新突破:可一次性打印出带骨骼、肌腱、韧带的机械手

原创 | 文 BFT机器人 近日&#xff0c;来自瑞士苏黎世联邦理工学院 (ETH) 和美国初创公司Inkbit的研究团队采用最新的激光扫描技术&#xff0c;成功地实现了机械手的3D打印&#xff0c;其内部结构由类人骨骼、韧带和肌腱组成。这项新技术使一次性3D打印具有弹性的特种塑料成为…

羊大师教你如何有效解决工作中的挑战与压力?

在现代社会&#xff0c;工作问题一直是许多人头疼的难题。无论是从工作压力到职业发展&#xff0c;工作问题不仅会影响个人的心理健康&#xff0c;还可能对整个工作团队的效率和和谐产生负面影响。因此&#xff0c;如何有效解决工作问题成为了每个职场人士都需要面对的挑战。 …

那仰望的人

心底的孤独和叹息

LangChain库简介

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

算法设计与分析复习--分支界限法

文章目录 上一篇分支界限法性质装载问题0-1背包问题单源最短路问题最大团问题下一篇 上一篇 算法设计与分析复习–回溯法&#xff08;二&#xff09; 分支界限法性质 分支界限法是按广度优先策略或最小耗费优先遍历问题的解空间树。 搜索解空间&#xff1a; 子集树排列树 …

python-opencv划痕检测-续

python-opencv划痕检测-续 这次划痕检测&#xff0c;是上一次划痕检测的续集。 处理的图像如下&#xff1a; 这次划痕检测&#xff0c;我们经过如下几步: 第一步&#xff1a;读取灰度图像 第二步&#xff1a;进行均值滤波 第三步&#xff1a;进行图像差分 第四步&#xff1…