【C++刷题】优选算法——动态规划第一辑

news2025/2/27 14:30:45
1.状态表示
	是什么?简答理解是dp表里的值所表示的含义
	怎么来的?
		题目要求
		经验+题目要求
		分析问题的过程中,发现重复子问题
2.状态转移方程
	dp[i]=......

细节问题:
	3.初始化
		控制填表的时候不越界
	4.填表顺序
		控制在填写当前状态的时候,所需要的状态已经填写好了
	5.返回值
		题目要求+状态表示

空间优化
	滚动数组
  1. 第 N 个泰波那契数
int tribonacci(int n)
{
    // 处理一些边界情况
    if(n < 3)
    {
        if(n == 0) return 0;
        else return 1;
    }

    // 1.创建dp表
    vector<int> dp(n + 1);
    // 2.初始化
    dp[0] = 0, dp[1] = 1, dp[2] = 1;
    for(int i = 3; i <= n; ++i)
    {
        // 3.填表
        dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
    }
    // 4.返回值
    return dp[n];
}
// 空间优化版本
int tribonacci(int n)
{
    int arr[3] = { 0,1,1 };
    if(n < 3) return arr[n];

    int ret = 0;
    for(int i = 3; i <= n; ++i)
    {
        ret = arr[0] + arr[1] + arr[2];
        arr[0] = arr[1], arr[1] = arr[2], arr[2] = ret;
    }
    return ret;
}
  1. 三步问题
状态表示:
	经验+题目要求:以i位置为结尾来入手
	dp[i]: 表示到达i位置,一共有多少种方法
状态转移方程:
	基于i位置状态,跨一步到i位置,来划分问题
int waysToStep(int n)
{
    if(1 == n) return 1;
    else if(2 == n) return 2;
    else if(3 == n) return 4;

    // 1.dp数组
    vector<int> dp(n + 1);
    // 2.初始化
    dp[1] = 1, dp[2] = 2, dp[3] = 4;
    for(int i = 4; i <= n; ++i)
    {
        // 3.状态方程
        dp[i] = ((dp[i - 1] + dp[i - 2]) % 1000000007 + dp[i - 3]) % 1000000007;
    }
    // 4.返回值
    return dp[n];
}
  1. 使用最小花费爬楼梯
状态表示:
	经验+题目要求:以i位置为结尾来入手
	dp[i]: 表示i位置到下一步的最小花费
状态转移方程:
	dp[i] = min(dp[i-1], dp[i-2]) + cost[i]
int minCostClimbingStairs(vector<int>& cost)
{
    // 1.dp数组
    vector<int> dp(cost.size());
    // 2.初始化
    dp[0] = cost[0]; dp[1] = cost[1];
    for (int i = 2; i < dp.size(); ++i)
    {
        // 3.状态转移方程
        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];
    }
    // 4.返回值
    return min(dp[dp.size() - 1], dp[dp.size() - 2]);
}
  1. 解码方法
状态表示:
	经验+题目要求:以i位置为结尾来入手
	dp[i]: 表示以i位置为结尾时,解码方法的总数
状态转移方程:

在这里插入图片描述

int numDecodings(string s)
{
    // 0.边界情况
    if(s.size() < 2)
    {
        if(s[0] == '0') return 0;
        else return 1;
    }
    // 1.dp数组
    vector<int> dp(s.size(), 0);
    // 2.初始化
    if (s[0] == '0') dp[0] = 0;
    else dp[0] = 1;
    if (s[0] != '0' && s[1] != '0') dp[1] += 1;
    if (10 <= stoi(s.substr(0, 2)) && stoi(s.substr(0, 2)) <= 26) dp[1] += 1;

    for(int i = 2; i < dp.size(); ++i)
    {
        // 3.状态转移方程
        int num1 =0, num2 = 0;
        if(s[i] != '0') num1 = dp[i - 1];
        if(10 <= stoi(s.substr(i - 1, 2)) && stoi(s.substr(i - 1, 2)) <= 26) num2 = dp[i - 2];
        dp[i] = num1 + num2;
    }
    // 4.返回值
    return dp.back();
}
  1. 不同路径
状态表示:
	经验+题目要求:以[i,j]位置为结尾来入手
	dp[i][j]: 表示以[i,j]位置为finish时,从start出发的不同路径数
状态转移方程:
	dp[i][j] = dp[i-1][j] + dp[i][j-1]
int uniquePaths(int m, int n)
{
    // 1.dp数组
    vector<vector<int>> dp(m, vector<int>(n));
    // 2.初始化
    for (int i = 0; i < m; ++i)
    {
        dp[i][0] = 1;
    }
    for (int i = 0; i < n; ++i)
    {
        dp[0][i] = 1;
    }
    // 3.状态转移方程
    for (int row = 1; row < m; ++row)
    {
        for (int col = 1; col < n; ++col)
        {
            dp[row][col] = dp[row - 1][col] + dp[row][col - 1];
        }
    }
    // 4.返回值
    return dp.back().back();
}
  1. 不同路径 II
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid)
{
    // 1.dp数组
    int m = obstacleGrid.size();
    int n = obstacleGrid[0].size();
    vector<vector<int>> dp(m, vector<int>(n));
    // 2.初始化
    for(int i = 0; i < m; ++i)
    {
        if(obstacleGrid[i][0] == 1)
            break;
        dp[i][0] = 1;
    }
    for(int i = 0; i < n; ++i)
    {
        if(obstacleGrid[0][i] == 1)
            break;
        dp[0][i] = 1;
    }
    // 3.状态转移方程
    for(int row = 1; row < m; ++row)
    {
        for(int col = 1; col < n; ++col)
        {
            if(obstacleGrid[row][col] == 1)
                continue;
            dp[row][col] = dp[row - 1][col] + dp[row][col - 1];
        }
    }
    // 4.返回值
    return dp.back().back();
}
  1. 珠宝的最高价值
状态表示:
	经验+题目要求:以[i,j]位置为结尾来入手
	dp[i][j]: 表示到达[i,j]位置时所能得到的的最大价值
状态转移方程:
	dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + frame[i][j]
int jewelleryValue(vector<vector<int>>& frame)
{
    // 1.dp数组
    int row = frame.size();
    int col = frame[0].size();
    vector<vector<int>> dp(row, vector<int>(col));

    // 2.初始化
    dp[0][0] = frame[0][0];
    for(int i = 1; i < col; ++i)
    {
        dp[0][i] = dp[0][i - 1] + frame[0][i];
    }
    for(int i = 1; i < row; ++i)
    {
        dp[i][0] = dp[i - 1][0] + frame[i][0];
    }

    // 3.状态转移方程
    for(int i = 1; i < row; ++i)
    {
        for(int j = 1; j < col; ++j)
        {
            dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + frame[i][j];
        }
    }

    // 4.返回值
    return dp.back().back();
}
  1. 下降路径最小和
状态表示:
	经验+题目要求:以[i,j]位置为结尾来入手
	dp[i][j]: 表示到达[i,j]位置时所得到的最小下降路径和
状态转移方程:
	dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i-1][j+1]) + frame[i][j]
    int minFallingPathSum(vector<vector<int>>& matrix)
    {
        // 1.dp数组
        int n = matrix.size();
        vector<vector<int>> dp(n, vector<int>(n));

        // 2.初始化
        for(int i = 0; i < n; ++i)
        {
            dp[0][i] = matrix[0][i];
        }

        // 3.状态转移方程
        for(int i = 1; i < n; ++i)
        {
            for(int j = 0; j < n; ++j)
            {
                if(j == 0)
                {
                    dp[i][j] = min(dp[i - 1][j], dp[i - 1][j + 1]) + matrix[i][j];
                }
                else if(j == n - 1)
                {
                    dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - 1]) + matrix[i][j];
                }
                else
                {
                    dp[i][j] = min(min(dp[i - 1][j - 1], dp[i - 1][j]), dp[i - 1][j + 1]) + matrix[i][j];
                }
            }
        }

        // 4.返回值
        int min_sum = dp[n - 1][0];
        for(int i = 1; i < n; ++i)
        {
            if(dp[n - 1][i] < min_sum) min_sum = dp[n - 1][i];
        }
        return min_sum;
    }
  1. 最小路径和
状态表示:
	经验+题目要求:以[i,j]位置为结尾来入手
	dp[i][j]: 表示到达[i,j]位置时所得到的最小路径和
状态转移方程:
	dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
int minPathSum(vector<vector<int>>& grid)
{
    // 1.dp数组
    int m = grid.size();
    int n = grid[0].size();
    vector<vector<int>> dp(m, vector<int>(n));

    // 2.初始化
    dp[0][0] = grid[0][0];
    for(int i = 1; i < m; ++i)
    {
        dp[i][0] = dp[i - 1][0] + grid[i][0];
    }
    for(int i = 1; i < n; ++i)
    {
        dp[0][i] = dp[0][i - 1] + grid[0][i];
    }

    // 3.状态转移方程
    for(int i = 1; i < m; ++i)
    {
        for(int j = 1; j < n; ++j)
        {
            dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
        }
    }

    // 4.返回值
    return dp.back().back();
}
  1. 地下城游戏
状态表示:
	经验+题目要求:以[i,j]位置为起点来入手
	dp[i][j]: 表示从[i,j]位置出发,到达终点,所需的最低初始健康点数
状态转移方程:
	dp[i][j] = min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j];
	dp[i][j] = max(1, dp[i][j]); // 细节处理,健康点数至少为1才能存活
int calculateMinimumHP(vector<vector<int>>& dungeon)
{
    // 1.dp数组
    int m = dungeon.size();
    int n = dungeon[0].size();
    vector<vector<int>> dp(m, vector<int>(n));

    // 2.初始化
    if(dungeon[m - 1][n - 1] < 0) dp[m - 1][n - 1] = 1 - dungeon[m - 1][n - 1];
    else dp[m - 1][n - 1] = 1;
    for(int i = n - 2; i >= 0; --i)
    {
        dp[m - 1][i] = dp[m - 1][i + 1] - dungeon[m - 1][i];
        dp[m - 1][i] = max(1, dp[m - 1][i]);
    }
    for(int i = m - 2; i >= 0; --i)
    {
        dp[i][n - 1] = dp[i + 1][n - 1] - dungeon[i][n - 1];
        dp[i][n - 1] = max(1, dp[i][n - 1]);
    }

    // 3.状态转移方程
    for(int i = m - 2; i >= 0; --i)
    {
        for(int j = n - 2; j >= 0; --j)
        {
            dp[i][j] = min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j];
            dp[i][j] = max(1, dp[i][j]);
        }
    }

    // 4.返回值
    return dp[0][0];
}

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

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

相关文章

windows下修改mysql的max_allowed_packet的值

1)C:\Program Files\MySQL\MySQL Server 5.7 在MySQL 的安装目录下添加my.ini文件&#xff0c;同时添加空的data文件 2&#xff09;my.ini文件内容如下&#xff0c; [mysqld] port 3306 basedirC:\Program Files\MySQL\MySQL Server 5.7 datadirC:\Program Files\MySQL\MySQ…

软考78-上午题-【面向对象技术3-设计模式】-结构型设计模式01

一、适配器模式 1-1、意图 个类的接口转换成客户希望的另外一个接口。 Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 1-2、结构 适配器模式分为&#xff1a; 1、适配器类模式&#xff1b; 2、适配器对象模式 类适配器使用多重继承对一个接口与另…

java基础(6) IO[下] 线程(补充) XML Servlet

输出流 OutputStream OutputStream是Java标准库提供的最基本的输出流。 和InputStream类似&#xff0c;OutputStream也是抽象类&#xff0c;它是所有输出流的超类。这个抽象类定义的一个最重要的方法就是void write(int b) public abstract void write(int b) throws IOExcep…

html--宠物

文章目录 htmljscss html <!DOCTYPE html> <html lang"en" > <head><meta charset"UTF-8"><title>CodePen - Spaceworm</title><script> window.requestAnimFrame (function() {return (window.requestAnimat…

Javascript抓取京东、淘宝商品数据(商品采集商品详情图片抓取)

之前用的方法&#xff1a; let temp []var lists $(#J_goodsList li.gl-item)$.each(lists,function(idx,item){ temp.push({ id:$(item).data(sku), goods_img:$(item).find(img).attr(src), goods_name:$(item).find(.p-name em).text(), market_price:$(item).fi…

2024 年(第 12 届)“泰迪杯”数据挖掘挑战赛——B 题:基于多模态特征融合的图像文本检索完整思路与源代码分享

一、问题背景 随着近年来智能终端设备和多媒体社交网络平台的飞速发展&#xff0c;多媒体数据呈现海量增长 的趋势&#xff0c;使当今主流的社交网络平台充斥着海量的文本、图像等多模态媒体数据&#xff0c;也使得人 们对不同模态数据之间互相检索的需求不断增加。有效的信…

洛谷P8972 『GROI-R1』 一切都已过去(树上前缀和+运算符重载)

『GROI-R1』 一切都已过去 题目背景 悦关上窗&#xff0c;拉上帘布。 果然还是想不起来啊。 隐约记得曾和什么人一起做过这样的事。 仰面躺下&#xff0c;手执一只木笺。 「究竟如何&#xff0c;才能拥有“过去”啊……」 她闭上双眼。 「6 岁前的记忆……究竟如何才能…

ConsiStory:Training-Free的主体一致性生成

Overview 一、总览二、PPT详解 ConsiStory 一、总览 题目&#xff1a; Training-Free Consistent Text-to-Image Generation 机构&#xff1a;NVIDIA, Tel-Aviv University 论文&#xff1a;https://arxiv.org/pdf/2402.03286.pdf 代码&#xff1a;https://consistory-paper.g…

Python自动获取指定上市公司的所有财务数据(资产负债表,利润表,现金流量表)

案例背景 很多经管类同学找财务数据都很困难&#xff0c;去找一个个查找特定的公司&#xff0c;然后又要去同花顺或者东方财富网一年一年的去查看报表&#xff0c;一年一年的数据一个个填入...太慢了。 tushare能获取金融数据的接口&#xff0c;他有资产负债表&#xff0c;利…

idea warning:java源值已过时将在未来所有发行版中删除

在idea中运行maven项目 如果出现idea warning:java源值已过时将在未来所有发行版中删除&#xff0c;详见如下截图所示&#xff1a; 注意&#xff1a;jdk8 要解决这个警告需要设置3个地方 首先打开File->Project Structure中的Project&#xff0c;将SDK和language level都设…

Java学习笔记(15)

JDK7前时间相关类 Date时间类 Simpledateformat Format 格式化 Parse 解析 默认格式 指定格式 EE&#xff1a;表示周几 Parse&#xff1a;把字符串时间转成date对象 注意&#xff1a;创建对象的格式要和字符串的格式一样 Calendar日历类 不能创建对象 Getinstance 获取当…

Python笔记|字符串合并、切片、索引

一、合并 字符串可以用 合并&#xff08;粘到一起&#xff09;&#xff0c;也可以用 * 重复&#xff1a; >>> 3 * un ium unununium 相邻的两个或多个字符串字面值&#xff08;引号标注的字符&#xff09;会自动合并&#xff1a; >>> Py thon Python …

蓝桥杯每日一题 走迷宫bfs 超超详细解释!!!

昨天学习了bfs的基本概念&#xff0c;今天来做一道经典习题练练手吧&#xff01; bfs常用的两类题型 1.从A出发是否存在到达B的路径(dfs也可) 2.从A出发到B的最短路径&#xff08;数小:<20才能用dfs&#xff09; 遗留的那个问题的答案- 题目&#xff1a;走迷宫 答案&…

【Java刷题篇】串联所有单词的子串

这里写目录标题 &#x1f4c3;1.题目&#x1f4dc;2.分析题目&#x1f4dc;3.算法原理&#x1f9e0;4.思路叙述✍1.进窗口✍2.判断有效个数✍3.维护窗口✍4.出窗口 &#x1f4a5;5.完整代码 &#x1f4c3;1.题目 力扣链接: 串联所有单词的子串 &#x1f4dc;2.分析题目 阅…

力扣L14--- 415.字符串相加(JAVA版)-2024年3月17日

1.题目 2.知识点 注1&#xff1a;你可以使用Integer.parseInt()或Double.parseDouble()等方法将字符串转换为整数或浮点数。 public class Main {public static void main(String[] args) {String str "123";int num Integer.parseInt(str);System.out.println(…

如何在Mac中删除照片?这里有详细步骤

前言 本文介绍如何从Mac中删除照片,以释放硬盘空间或更好地组织文件和文件夹。 如何使用废纸篓删除Mac上的图片 在Mac上删除图片的最简单方法之一是使用废纸篓功能。学习只需几秒钟。下面是如何删除单个图片以及如何在Mac上删除多个图片,以及一些关键和有用的提示,以使该…

2023全球国际专利申请数量公布:华为遥遥领先三星、高通、苹果~

华为、三星和高通在2023年的国际专利申请数量上位居前三甲&#xff0c;其中来自中国的公司大幅度超越韩国和美国的高科技竞争对手。世界知识产权组织&#xff08;WIPO&#xff09;最新发布的数据显示&#xff0c;即使面临美国严厉制裁严重影响其在全球市场的运作能力&#xff0…

HTML静态网页成品作业(HTML+CSS)——家乡广州介绍设计制作(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有5个页面。 二、作品演示 三、代…

AI泳池溺水识别摄像机

AI泳池溺水识别摄像机是一种利用人工智能技术来监测和识别游泳池中溺水行为的智能监控设备。通过深度学习算法和图像识别技术&#xff0c;该摄像机能够实时捕捉游泳池的画面&#xff0c;自动分析水面动态和人员行为&#xff0c;判断是否有溺水事件发生&#xff0c;并及时发出警…

浅谈虚拟机下部分内网穿透功能实现方法

新钛云服已累计为您分享789篇技术干货 最近个人搭建服务器的情况有所增长&#xff0c;简单介绍一下一些可以使得服务器能被公网ip访问的方法。内网穿透一般用于将位于内部私有网络&#xff08;如家庭网络&#xff09;的服务暴露到公共网络&#xff08;如互联网&#xff09;上&a…