刷题之动态规划-路径问题

前言

大家好,我是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];
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

鹰眼降尘系统的维护成本高吗(已解答)

一、鹰眼降尘系统的维护成本高吗? 鹰眼降尘系统的维护成本会受到多种因素的影响&#xff0c;包括系统的规模、使用频率、设备质量、维护计划等。一般来说&#xff0c;合理的维护可以降低成本并延长系统的使用寿命。 以下是一些影响鹰眼降尘系统维护成本的因素&#xff1a; 设…

Codigger开发者篇:开启全新的开发体验(三)

Codigger&#xff0c;作为一个集开发、运营与使用私人应用于一体的分布式操作系统&#xff0c;以其独特的魅力与优势&#xff0c;为开发者们打开了全新的世界大门&#xff0c;引领他们迈向了一个前所未有的开发体验之旅。在之前的篇章中&#xff0c;我们已经深入探讨了Codigger…

实时监控iOS应用程序运行日志的工具分享

目录 一、设备连接 二、使用克魔助手查看日志 三、过滤我们自己App的日志 &#x1f4dd; 摘要&#xff1a; 本文介绍了如何在iOS iPhone设备上实时查看输出在console控制台的日志。通过克魔助手工具&#xff0c;我们可以连接手机并方便地筛选我们自己App的日志。 &#x1f4…

智慧公厕:改变城市生活的革命性基础设施

在现代城市的高品质生活要求背景下&#xff0c;公共厕所成为了不可或缺的基础设施。然而&#xff0c;传统的公厕在服务质量、管理效率方面存在一定的问题。为了提供更好的公厕服务&#xff0c;智慧公厕应运而生。通过智能化的管理模式&#xff0c;智慧公厕实现了公厕使用与管理…

C++11标准 - 声明(auto,decltype,nullptr)

C11标准 - 声明&#xff08;auto&#xff0c;decltype&#xff0c;nullptr&#xff09; 前言1. auto2. decltype3. nullptr 前言 c11提供了多种简化声明的方式&#xff0c;尤其是在使用模板时。 1. auto 在C98中auto是一个存储类型的说明符&#xff0c;表明变量是局部自动存…

[蓝桥杯 2019 省赛 AB] 完全二叉树的权值

# [蓝桥杯 2019 省 AB] 完全二叉树的权值 ## 题目描述 给定一棵包含 $N$ 个节点的完全二叉树&#xff0c;树上每个节点都有一个权值&#xff0c;按从上到下、从左到右的顺序依次是 $A_1,A_2, \cdots A_N$&#xff0c;如下图所示&#xff1a; 现在小明要把相同深度的节点的权值…

移动硬盘怎么加密?移动硬盘加密软件有哪些?

移动硬盘是我们在工作中最常用的移动存储设备&#xff0c;为了保护数据安全&#xff0c;需要使用专业的移动硬盘加密软件加密保护。那么&#xff0c;移动硬盘加密软件有哪些&#xff1f; ​BitLocker BitLocker是Windows的磁盘加锁功能&#xff0c;可以用于加密保护移动硬盘中…

Devin、OpenDevin

文章目录 关于 DevinCognition 公司Devin 的能力 关于 OpenDevin⭐️ Research Strategy&#x1f6e0; Technology Stack 使用 OpenDevin安装选择一个 Model在命令行运行 关于 Devin Cognition 发布了世界上第一个完全自主的人工智能软件工程师 Devin&#xff0c;在 SWE-bench…

Bert基础(九)--Bert变体之ALBERT

在接下来的几篇&#xff0c;我们将了解BERT的不同变体&#xff0c;包括ALBERT、RoBERTa、ELECTRA和SpanBERT。我们将首先了解ALBERT。ALBERT的英文全称为A Lite version of BERT&#xff0c;意思是BERT模型的精简版。ALBERT模型对BERT的架构做了一些改变&#xff0c;以尽量缩短…

【C++】vector系列力扣刷题日志(136.只出现一次的数字,118.杨辉三角,26.删除有序数组中的重复项,260.只出现一次的数字 |||)

目录 136.只出现一次的数字 118.杨辉三角 26.删除有序数组中的重复项 260.只出现一次的数字 ||| vector的详细介绍及用法这里就不过多赘述了&#xff0c;可以参考上一篇博客&#xff1a;vector的介绍及使用说明 136.只出现一次的数字 题目&#xff1a; 给你一个 非空 整数…

深入理解鸿蒙生命周期:从应用到组件

在开发鸿蒙&#xff08;HarmonyOS&#xff09;应用时&#xff0c;理解生命周期的概念至关重要。生命周期不仅关乎应用的性能优化&#xff0c;还涉及到资源管理和用户体验等多个方面。本文将详细解析鸿蒙操作系统中应用、页面和组件的生命周期&#xff0c;帮助开发者更好地掌握这…

炸裂,PG的FDW又进化了!

&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&#x1f61c;&#x1f61c; 中国DBA联盟(ACD…

Python 用pygame简简单单实现一个打砖块

# -*- coding: utf-8 -*- # # # Copyright (C) 2024 , Inc. All Rights Reserved # # # Time : 2024/3/30 14:34 # Author : 赫凯 # Email : hekaiiii163.com # File : ballgame.py # Software: PyCharm import math import randomimport pygame import sys#…

C++:加减乘除运算符(14)

就是常用的一些算数符 正1010负-10-10加102030减10 - 20-10 乘 10 * 20200除10 / 200.5 加 简单的加法运算 #include<iostream> using namespace std;int main() {// 加减乘除int a1 10;int b1 20;cout << a1 b1 << endl;system("pause");ret…

鸿蒙OS开发实战:【ArkTS 实现MQTT协议(2)】

软件说明 协议传输通道仅为TCPSocket基于HarmonyOS SDK API 9开发开发语言&#xff1a;ArkTS&#xff0c;TypeScript 应用操作说明 测试首页 “连接” : 用于连接远端服务器。具备“连接 & 断开” 两个功能“设置” : 用于添加更多主题“订阅” & “解除” : 仅用于…

LLM:函数调用(Function Calling)

1 函数调用 虽然大模型能解决很多问题&#xff0c;但大模型并不能知晓一切。比如&#xff0c;大模型不知道最新消息(GPT-3.5 的知识截至 2021年9月&#xff0c;GPT-4 是 2023 年12月)。另外&#xff0c;大模型没有“真逻辑”。它表现出的逻辑、推理&#xff0c;是训练文本的统计…

第九节:时间队列(终结篇)

一、概述 在常规的时间管理中是时间到了触发某个任务&#xff0c;这样一个时间点对应一个任务。在特殊的场景下&#xff0c;任务不断放送到时间队列&#xff0c;时间一到&#xff0c;全部任务执行并释放。如图&#xff1a; 二、时间队列组件 SMB提供了TimeFragment组件来构建…

Domino中的Web博客还能这么用

大家好&#xff0c;才是真的好。 最近时间比较空余&#xff08;闲得慌&#xff09;&#xff0c;计划做一个网站出来。虽然网站很不流行&#xff0c;但对80后程序员来说&#xff0c;毕竟容易实现和感觉亲切。 在Domino平台上做一个网站实在是太容易了&#xff0c;但除了手动开…

【Linux】IP协议

目录 IP报头格式 网段划分 特殊的IP地址 IP地址的数量限制 私有IP地址和公网IP地址 路由 IP报文分片 1.粗粒度谈谈分片 a. 确保将所有的分片全部聚到一起&#xff08;相同的标识&#xff09; b. 片偏移排序&#xff08;完成组转&#xff09; 2.分片细节 数据链路层 M…

http模块 服务器端如何响应(获取)静态资源?

一、静态资源与动态资源介绍&#xff1a; &#xff08;1&#xff09;静态资源 内容长时间不改变的资源。eg&#xff1a;图片、视频、css js html文件、字体文件... &#xff08;2&#xff09;动态资源 内容经常更新的资源。eg&#xff1a;百度首页、淘宝搜索列表... 二、服…