刷题之动态规划

news2025/2/1 17:00:51

前言

大家好,我是jiantaoyab,开始刷动态规划的题目了,要特别注意初始化的时候给什么值。

动态规划5个步骤

  1. 状态表示 :dp数组中每一个下标对应值的含义是什么->dp[i]表示什么
  2. 状态转移方程: dp[i] 等于什么
  3. 1 和 2 是动态规划的核心步骤,第三步是初始化,保证填表的时候不越界
  4. 填表顺序:为了保证填写当前状态的时候,所需要的状态已经计算过
  5. 返回值

第 N 个泰波那契数

image-20240327082552013

题目分析

image-20240327082930486

我们用动态规划来解决

  1. dp[i] : 表示第i个泰波那契数
  2. dp[i] = dp[i - 3] + dp[i - 2] + dp [i - 1]
  3. 初始化: dp[0] = 0; dp[1] = 1 ; dp[2] = 1;
  4. 填表顺序:从左道右
  5. 返回值:dp[n]

代码

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

image-20240327085917789

优化一下,可以看到只需要三个变量也能完成这个操作。

class Solution {
public:
    int tribonacci(int n) {
      if(n == 0) return 0;
      if(n == 1 || n == 2) return 1;
      int a = 0, b = 1, c = 1, d = 0;
      for(int i = 3; i <= n; i++)
      {
        d = a + b + c;
        a = b;
        b = c;
        c = d;
      }
      return d;
    }
};

三步问题

image-20240327090422340

image-20240327093241354

题目分析

  1. dp[i] :表示去到当前台阶有几种方法
  2. dp[i] = dp[i-1] + dp[i-2] + dp[i-3]
  3. 初始化 dp[1] = 1; dp[2] = 2; dp[3] = 4;
  4. 填表顺序从左到右
  5. 返回值 d[n]

代码

class Solution {
public:
    int waysToStep(int n) {
      vector<int>dp(n + 1);
      if(n == 1 || n == 2) return n;
      if(n == 3) return 4;
      const int MOD = 1000000007;
      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];
    }
};

使用最小花费爬楼梯

image-20240327094348136

题目分析

image-20240327102746297

  1. dp[i]:到达 i位置的最小花费
  2. dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]);
  3. 初始化:dp[0] = dp[1] = 0;
  4. 填表顺序:从左到右
  5. 返回值:dp[n]

代码

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
      int n = cost.size();
      vector<int> dp(n + 1);
      dp[0] = dp[1] = 0;
      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];
      
    }
};

解码方法

image-20240328121136322

题目分析

image-20240328124124445

  1. dp[i]:是表示是 i 位置为结尾的解码方法总数
  2. dp[i] = dp[i - 1] + dp [i - 2];
  3. 初始化:dp[0] = 0 / 1 dp[1] = 0/ 1/ 2
  4. 填表顺序:从左到右
  5. 返回值:dp[n - 1]

代码

class Solution {
public:
    int numDecodings(string s) {
      int n = s.size();
      vector<int> dp (n);
      
      //初始化
      dp[0] = s[0] != '0';
      if(n == 1) return dp[0];
      if(s[0] != '0' && s[1] != '0') dp[1] += 1;
      int tmp = (s[0] - '0') * 10 + (s[1] - '0');
      if(tmp >= 10 && tmp <= 26) dp[1] += 1;
      
      //处理剩下的
     for(int i = 2; i < n; i++)
     {
      //单独一个字符
        if(s[i] != '0') dp[i] += dp[i - 1];
      //2个字符
        int tmp = (s[i - 1] - '0') * 10 + (s[i] - '0');
        if(tmp >= 10 && tmp <= 26) dp[i] += dp[i - 2];
     }
      return dp[n - 1];
    }
};

优化代码

image-20240328132736524

class Solution {
public:
    int numDecodings(string s) {
      int n = s.size();
      vector<int> dp (n + 1); 
      //初始化
      dp[0] = 1;
      dp[1] = s[1 - 1] != '0';  
      //处理剩下的
     for(int i = 2; i <= n; i++)
     {
      //单独一个字符
        if(s[i - 1] != '0') dp[i] += dp[i - 1];
      //2个字符
        int tmp = (s[i - 2] - '0') * 10 + (s[i - 1] - '0');
        if(tmp >= 10 && tmp <= 26) dp[i] += dp[i - 2];
     }
      return dp[n];
    }
};

不同路径

image-20240328133027939

题目分析

image-20240328142217131

  1. dp[i] [j]:走到 i,j 位置有多少种方式
  2. dp[i] [j] = dp[i] [j - 1] + dp[i - 1] [j];
  3. 初始化:新增加一列和一行
  4. 填表顺序:从上到下,左到右填表
  5. 返回值:dp[m] [n]

代码

class Solution {
public:
    int uniquePaths(int m, int n) {
        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++)
          {
            dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
          }
        }
        return dp[m][n];
    }
};

不同路径 II

image-20240328142046409

题目分析

  1. dp [i] [j] : 到达i,j这个位置有多少种方法
  2. dp [i] [j] = dp[i - 1] [j] + dp [i] [j - 1]
  3. 初始化:dp[1] [0] = 1;
  4. 填表顺序:从上到下,从左到右
  5. 返回值: dp[m] [n]

代码

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[1][0] = 1;
          for(int i = 1; i <= m; i++)
          {
            for(int j = 1; j <= n; j++)
            {
              if(obstacleGrid[i - 1][j - 1] != 1)
              dp[i][j] = dp[i - 1][j] + dp[i][j -1];
            }

          }
          return dp[m][n];
    } 
};

珠宝的最高价值

image-20240329083509134

题目分析

  1. dp [i] [j] : 到达i,j这个位置的最高价值
  2. dp [i] [j] =max(dp[i-1] [j], dp[i] [j-1]) + frame[i-1] [j-1];
  3. 初始化:默认都是0不用初始化
  4. 填表顺序:从上到下,从左到右
  5. 返回值: dp[m] [n]

代码

class Solution {
public:
    int jewelleryValue(vector<vector<int>>& frame) {
        int m = frame.size(), n = frame[0].size();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1));
        for(int i = 1; i <= m; i++)
          for(int j = 1; j <= n; j++)
          {           
            dp[i][j] =  max(dp[i-1][j], dp[i][j-1]) + frame[i-1][j-1];
          }
        return dp[m][n];
    }
};

下降路径最小和

image-20240329090000519

题目分析

  1. dp[i] [j] : 到达i,j位置的最小下路径
  2. dp[i] [j] : min(dp[i+1] [j-1], dp[i+1] [j+1], dp[i+1] [j]) + matrix[i-1] [j - 1]
  3. 初始化:多给1行 和2列
  4. 填表顺序:从上到下,从左到右
  5. 返回值: 最后一行的最小值

image-20240329093844878

代码

class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& matrix) {
     int n = matrix.size();
     vector<vector<int>> dp(n + 1, vector<int>(n + 2, INT_MAX));
      for(int j = 0; j < n + 2; j++) dp[0][j] = 0;
      for(int i = 1; i <= n; i++)
      {
         for(int j = 1; j <= n; j++)
        {
          dp[i][j] = min(min(dp[i-1][j-1], dp[i-1][j]), dp[i-1][j+1]) + matrix[i-1][j-1];
        }
      
      }      
      //返回值
      int ret = INT_MAX;
      for(int j = 1; j <= n; j++)
      {
        ret = min(ret, dp[n][j]);
      }
      return ret;
    }
};

最小路径和

image-20240329094117164

代码

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int m = grid.size(), n = grid[0].size();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX));
        dp[1][0] = dp[0][1] = 0; 
        for(int i = 1; i <= m; i++)
          for(int j = 1; j <= n; j++)
          {
            dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i - 1][j - 1];
          }
        
      return dp[m][n];
    }
};

地下城游戏(反着来)

image-20240329102706154

题目分析

image-20240329105223745

  1. dp[i] [j] : 从i,j位置出发,到达终点所需要的最低

  2. dp[i] [j] = min(dp[i] [j + 1], dp[i + 1] [j]) - dungeon[i] [j];

  3. 初始化 dp[m +1] [n -1] = dp [m - 1] [n + 1] = 1;

  4. 填表顺序:从下到上,从右到左

  5. 返回值: dp[0] [0]

代码

class Solution {
public:
    int calculateMinimumHP(vector<vector<int>>& dungeon) {
      int m = dungeon.size(), n = dungeon[0].size();
      vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX));
      //初始化
      dp[m][n -1] = dp [m - 1][n] = 1;
      for(int i = m - 1; i >= 0; i--)
        for(int j = n - 1; j >= 0; j--)
        {
          dp[i][j] = min(dp[i][j + 1], dp[i + 1][j]) - dungeon[i][j];
          dp[i][j] = max(1, dp[i][j]); //如果血包很大,会出现负数,这里取1就是最低血
          
        }
        return dp[0][0];
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++项目——集群聊天服务器项目(六)MySQL模块

Hello&#xff0c;大家好啊&#xff0c;最近比较忙&#xff0c;没来得及更新项目&#xff0c;实在抱歉~今天就恢复更新拉~ 在验证完网络模块与业务模块代码可以正常使用后&#xff0c;需完成的操作是与底层数据库进行交互&#xff0c;为实现各类用户查询、增删业务奠定良好的基…

C语言goto语句介绍

在C语言中&#xff0c;goto语句是一种流程控制语句&#xff0c;用于无条件地转移到程序中的特定标签位置。尽管goto语句在编程中具有一定的争议&#xff0c;但在某些情况下&#xff0c;它可以提供一种简单有效的解决方案。本文将深入介绍C语言中的goto语句&#xff0c;包括其基…

量化交易入门(二十九)布林带指标实现和回测

首先我们来看一张图&#xff0c;这张图就是拿的苹果股票2020年1月1日到2023年12月30日的历史数据进行回测后生成的。图中绿色箭头是买入点&#xff0c;红色箭头是卖出点。我们看到大部分的时候是在股价较低的时候买入&#xff0c;在股价较高的时候卖出&#xff0c;好像挺不错的…

K8s Pod亲和性、污点、容忍度、生命周期与健康探测详解(中)

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Kubernetes航线图&#xff1a;从船长到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 在上一章节中&#xff0c;我们详细探讨了Pod的亲和性&…

计算机网络(第八版)-第1章课后习题参考答案

计算机网络(第八版)-第1章课后习题参考答案 本文是对自己之前文章的格式化&#xff1a;https://blog.csdn.net/qq_46396470/article/details/132788972?spm1001.2014.3001.5502 T1-01 计算机网络向用户可以提供哪些服务&#xff1f; 连通性和共享 &#xff0c;例如音频&…

Lecture 1 - Introduction

Lecture 1 - Introduction MIT 6.824 Distributed Systems 1、概念预览 分布式系统需要考虑的因素&#xff1a; Parallelism &#xff1a;并行性Fault tolerence &#xff1a;容错性Physicial &#xff1a;不同系统之间物理距离引起的通信问题**Security ** &#xff1a;不…

WPF 路由事件 数据驱动 、Window 事件驱动

消息层层传递&#xff0c;遇到安装有事件侦听器的对象&#xff0c;通过事件处理器响应事件&#xff0c;并决定事件是否继续传递&#xff1b; 后置代码中使用AddHandler方法设置事件监听器&#xff0c;该方法的 第一个参数是指定监听的路由事件类型对象&#xff0c; 第二个参数…

3.29 day1 freeRTOS

1.总结keil5下载代码和编译代码需要注意的事项 注意要将魔术棒的的debug选项中的setting中的flashdownload中的reset and run 勾选上&#xff0c;同时将pack中的enable取消勾选 2.总结STM32Cubemx的使用方法和需要注意的事项 可以通过功能列表对引脚进行设置&#xff0c;并且可…

153 Linux C++ 通讯架构实战8 ,日志打印实战,设置时区,main函数中顺序调整

日志打印实战 //日志的重要性&#xff1a;供日后运行维护人员去查看、定位和解决问题&#xff1b; //新文件&#xff1a;ngx_printf.cxx以及ngx_log.cxx。 //ngx_printf.cxx&#xff1a;放和打印格式相关的函数&#xff1b; //ngx_log.cxx&#xff1a;放和日志相关…

[Python人工智能] 四十五.命名实体识别 (6)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型(注意力问题探讨)

从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前文讲解融合Bert的实体识别研究,使用bert4keras和kears包来构建Bert+BiLSTM-CRF模型。这篇文章将详细结合如何利用keras和tensorflow构建基于注意力机制的CNN-BiLSTM-ATT-CRF模型,并实现中文实体识别…

bugku-web-本地管理员

在页面源码的最右段发现一个base加密数据 dGVzdDEyMw 解密后 test123 将test作为账号123为密码尝试 说这个ip被禁止访问 那么问题应该出现在ip上 这里将请求报文抓取下来 POST / HTTP/1.1 Host: 114.67.175.224:18838 Content-Length: 18 Cache-Control: max-age0 Upgrade-Ins…

CTF题型 php://filter特殊编码绕过小汇总

CTF题型 php://filter特殊编码绕过小汇总 文章目录 CTF题型 php://filter特殊编码绕过小汇总特殊编码base64编码string过滤器iconv字符集 例题1.[Newstarctf 2023 week2 include]2.[Ctfshow web 117] php://filter 是一个伪协议&#xff0c;它允许你读取经过过滤器处理的数据流…

MHA 高可用配置 及故障切换

目录 一 什么是 MHA 1, MHA 概念 2&#xff0c;MHA 架构 2,1 传统mysql 架构存在问题 2.2 MHA高可用 3&#xff0c;MHA 的组成 4&#xff0c;数据同步方式 4.1 同步复制 4.2 异步复制 ​编辑 4.3 半同步复制 5&#xff0c;MHA 的特点 6&#xff0c; MHA工作原理…

OpenAI发布Voice Engine模型!用AI合成你的声音!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

解决WSL更新速度慢的方案

在Windows上安装Docker Desktop时&#xff0c;如果选择使用WSL&#xff0c;则可能会出现在运行程序前要求升级WSL的步骤。程序会提示使用下面指令来升级 wsl.exe --update但是升级速度特别慢&#xff0c;于是在网络不稳定的情况下经常会出现下载失败的情况。 百度里一直没搜到…

shell的工作原理

本文旨在讲解shell的工作原理&#xff0c;希望读完本文&#xff0c;能使读者对shell的工作原理有一定的认识&#xff0c;废话不多说&#xff0c;开唠&#xff01; 在讲解shell的工作原理之前&#xff0c;我要首先给大家讲一下什么是操作系统&#xff0c;以Linux操作系统为例&am…

【Springboot整合系列】SpringBoot整合WebService

目录 Web服务介绍Web服务的两种类型Web服务架构Web服务的主要特点Web服务使用场景Web服务标准和技术 WebService介绍WebService的作用适用场景不适用场景 WebService的原理三个角色相关概念 WebService开发框架代码实现服务端1.引入依赖2.实体类3.业务层接口接口实现类 4.配置类…

vue中使用图片url直接下载图片

vue中使用图片url直接下载图片 // 下载图片downloadByBlob(url, name) {let image new Image()image.setAttribute(crossOrigin, anonymous)image.src urlimage.onload () > {let canvas document.createElement(canvas)canvas.width image.widthcanvas.height image…

YoloV8实战:使用YoloV8检测钢材表面缺陷

摘要 本文讲解一下实战,使用YoloV8检测钢材表面缺陷。起因是有粉丝搞不定这个数据集,检测的时候出现了不收敛的情况。所以,给大家讲讲如何去做。 不收敛的原因 一般遇到不收敛的情况,就是数据转化的时候出错了,大家可以打开runs下面的训练日志,观察一下是否正常。 如…

CTF题型 nodejs(2) Js沙盒vmvm2逃逸原理总结典型例题

CTF题型 nodejs(2) Js沙盒逃逸原理&典型例题 文章目录 CTF题型 nodejs(2) Js沙盒逃逸原理&典型例题一.vm原理以及逃逸1.基本用法2.如何逃逸汇总1)this为对象2)this为null( Object.create(null))a .可用输出直接触发toString方法b.调用属性触发 3)Object.create(null)沙…