首页 > 其他分享 >关于动态规划

关于动态规划

时间:2025-01-18 22:21:12浏览次数:1  
标签:初始化 递归 int 递推 关于 数组 动态 规划 dp

主要问题大概是动规基础(斐波那契),背包,打家劫舍,股票,子序列。
解决也主要是先分类,建立dp数组,明确dp数组的含义,dp数组的初始化,遍历顺序。
动规基础斐波那契数列,爬楼梯,建立dp数组的时候,递推公式的推导就要参考建立dp数组并且明确dp数组的含义
比如下面的最小花费爬楼梯,明确含义就可以在爬楼梯的原有递推公式上进行修改,在对应的部分添加上相应的花费就可以找到新的递推公式,动规的其他问题找递推公式也是在明确建立的dp数组的含义后进行对应的推导,从而得出相应的递推公式。
dp[i]=dp[i-2]+dp[i-1]
上到n阶的方法数为n-2阶加上n-1阶
dp[i] = fmin(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]
上到n阶的最小花费为第n-2阶的最小花费加上n-1阶的最小花费
递推公式中的加一减一之类的也是在明确了dp数组的含义之后才好定下来,在不同路径问题中比较明显
dp[i][j]=dp[i-1][j]+dp[i][j-1]
这里的i和j分别代表着网格中的列和行,对应的加减就代表着左右方向,加减的数量就表示了具体的格子坐标
dp数组的初始化也要视不同情况而定,像在不同路径中,对于行和列的初始化都是1,但是在不同路径Ⅱ中的初始化就要考虑到因为存在障碍物以及限制了方向,所以有些格子需要初始化为0,而不能完全的全都初始换为1.
遍历的顺序也要根据情况而定,主要是从前到后和从后向前,但有些特殊的问题两层循环的顺序也要考虑到。
在解决动规问题的过程中,最先想到的通常是暴力,但是很多时候会超限,然后递归也可能会超限,可以尝试着用记忆化搜索和递推方法还有滚动数组,这些方法可以大幅度的缩减所需要的时间和内存。
记忆化搜索实在递归的基础上添加了一个用于储存计算结果的功能,因为在某些问题当中使用递归会造成大量的重复运算,添加了这个功能之后就可以避免因重复计算导致的时间浪费。
例:leetcode LCR 127

这题中如果直接使用递归会导致超时,无法通过测试用例(如图)

这时候我们可以使用记忆化搜索的方式来节约时间
`#define MOD 1000000007

int trainWays(int num) {
if (num < 0) {
return 0;
}

int vis[num + 1];
for (int i = 0; i <= num; i++) {
    vis[i] = -1;
}

int dfs(int n) {
    if (vis[n] != -1) {
        return vis[n];
    }
    if (n == 0 || n == 1) {
        return 1;
    }
    vis[n] = (dfs(n - 1) % MOD + dfs(n - 2) % MOD) % MOD;
    return vis[n];
}

return dfs(num);

}`
例:leetcode 392


同样直接使用递归会导致超时(如下图)


下为使用滚动数组的方法

int longestCommonSubsequence(char* text1, char* text2) { int m = strlen(text1); int n = strlen(text2); int dp[2][n + 1]; for (int i = 0; i <= 1; i++) { for (int j = 0; j <= n; j++) { dp[i][j] = 0; } } int now = 0, pre = 1; for (int i = 1; i <= m; i++) { now = 1 - now; pre = 1 - pre; for (int j = 1; j <= n; j++) { if (text1[i - 1] == text2[j - 1]) { dp[now][j] = dp[pre][j - 1] + 1; } else { dp[now][j] = dp[pre][j] > dp[now][j - 1]? dp[pre][j] : dp[now][j - 1]; } } } return dp[now][n]; }

标签:初始化,递归,int,递推,关于,数组,动态,规划,dp
From: https://www.cnblogs.com/Fwy040611/p/18678957

相关文章

  • 动态代理IP池管理:避免爬虫被封禁的高效策略
    在进行大规模数据抓取时,反爬虫机制经常成为爬虫开发者的一大难题。许多网站通过监测请求频率、User-Agent、IP地址等信息来识别并封禁爬虫。为了防止这种情况,动态代理IP池的管理变得尤为重要。通过使用代理IP池,并定期更换IP,可以有效避开基于IP的封禁策略。本篇博客将深入......
  • 关于我的博客建站经历
    我是一名前端开发工程师,从大四的时候开始自学前端,荒废了三年时光,在大四的时候才算真正走进“编程”这扇大门。也是从那个时候开始学着搭建自己的个人博客,用来记录自己的学习笔记,但是却坚持不下来。而且发现一个奇怪的现象,对于搭建站点的过程我很感兴趣,内容输出却坚持不下......
  • 动态规划
    在其他博客看到的一句话:计算机归根结底只会做一件事情——穷举;所有的算法都是如何让计算机“聪明”的穷举。什么是动态规划动态规划是将复杂问题分解成小问题求解的策略,与分治算法不同的是,分治算法要求各个子问题是相互独立的,而动态规划各个子问题是相互关联的。自顶向下递归......
  • 使用Axios实现表格数据动态加载与转换
    在现代的Web开发中,前后端分离架构越来越普遍。前端页面通过Ajax请求从后端获取数据并进行展示是一种常见的需求。本文将通过一个简单的示例,介绍如何使用Vue.js结合ElementUI以及Axios库,实现表格数据的动态加载与转换。一、项目背景在开发一个会员管理系统时,我们需要在前端页......
  • 1. 数码管的静态动态控制
    数码管,我的超级LED![[Pastedimage20250116130225.png]]![[Pastedimage20250116134916.png]]![[Pastedimage20250116130421.png]]多个数码管共引脚连接节省接口在同一个时刻相同引脚的数码管只能显示相同内容动态数码管显示是根据人眼视觉残留与数码管余辉实现的图中C......
  • 关于网传微信聊天记录提取工具"留痕"盗取个人信息的分析
    今天早上看到一篇文章,是关于一个微信聊天记录提取工具泄露个人信息的内容,于是我就好奇,看了一下作者的github,然后也是自己小小的分析了一下1、官方地址Github:https://github.com/LC044/WeChatMsg2、作者自证url:https://github.com/LC044/WeChatMsg/issues/4923、本地实践......
  • 关于函数(20250117)
    补充递归调用的补充:无限制的递归调用不会产生死循环,而是在栈区空间中,被调函数“入栈(保护现场)”产生的返回值地址占满整个栈区空间,程序直接崩溃。数组作为参数传递,传递的是数组的首元素地址。字符串数组的末尾存在‘\0’,因此字符串数组作为函数参数时,不需要元素个数作为函数参......
  • 全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南
    系列文章目录01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南02-玩转LangChainMemory模块:四种记忆类型详解及应用场景全覆盖03-全面掌握LangChain:从核心链条构建到动态任务分配的实战指南文章目录系列文章目录前言一、LangChain的核心链简介1.1......
  • 动态排名
    考虑一下正确性:在递归树上任意一点,任意一个查询操作,所有对其的影响一定会计入到树状数组中。分情况讨论。对于最开始的初始化操作,所有在\([L,R]\)的操作肯定都在当前操作序列的最前面。对于后面的修改操作,如果是\(-1\)标记,那么其对应的添加操作一定也在当前操作序列里面,而且在这个......
  • 【c++】【算法】【动态规划】最长公共子序列
    【c++】【算法】【动态规划】最长公共子序列//递归方式//最长公共子序//直接递归求最长公共子序长度intFindValue(conststring&X,conststring&Y,inti,intj){ if(i==0||j==0)return0; if(X[i]==Y[j])returnFindValue(X,Y,i-1,j-1)+1; ......