算法篇——动态规划

核心思想:

将问题分解为重叠的子问题,并储存子问题的解(使用字典、数组或哈希表),避免重复计算,从而提高效率。

题目特点:重叠子问题(特殊地,是最优子结构)

比如:斐波那契数列问题中,递归求F(5),需要多次计算F(3);

最短路径问题中,若从A到C的最优路径包含B,则A到B和B到C也必然是最优的。

两种实现方式:

自顶向下(递归+储存记忆,将大问题逐步分解,子问题的解储存在字典里):

class Solution(object):# 把momory作为类属性memory = {}def fib(self, n):# 如果已经在记忆里储存,则直接返回,不用再重复计算if n in self.memory: return self.memory[n]if n<=1:return nself.memory[n] = self.fib(n-1)+self.fib(n-2)return self.memory[n]

自底向上(迭代+储存记忆,先解决小问题再解决大问题,小问题的解储存在数组里):

class Solution(object):def fib(self, n):""":type n: int:rtype: int"""dp = [0,1] # 动态规划数组,初始值相当于递归里遇到终止条件能直接返回的值for i in range(2,n+1):dp.append(dp[i-1]+dp[i-2])return dp[n]

解题步骤:

1、定义状态(dp[i]表示什么)

2、写状态转移方程(由局部最优一直推到全局最优,所以从初始截断到当前位置来考虑即可,后面的先不管)

3、确定初始状态(起码两个)

3、用递归or迭代解题

比如:“打家劫舍”求数组中不相邻元素组合,使值的和最大

(1)定义状态:设dp[i]表示从第0到第i个中元素组合的最优解;

(2)状态转移方程:

则可以分类讨论:目前最优解要不要加上dp[i]这个元素,

即是取dp[i-1]还是dp[i-2]+nums[i],

比较两者取较大值就行。

得方程,dp[i] = max(dp[i-1],dp[i-2]+nums[i])

(3)初始条件:dp[0]=1,dp[1]=max(nums[0],nums[1])

class Solution(object):def rob(self, nums):""":type nums: List[int]:rtype: int"""n = len(nums)if n==1:return nums[0]dp = [nums[0],max(nums[0],nums[1])] #注意基础条件里,nums[1]不一定有,需要分类讨论for i in range(2,n):dp.append(max(dp[i-1],dp[i-2]+nums[i]))return dp[n-1]

删除并获得点数

class Solution(object):def deleteAndEarn(self, nums):""":type nums: List[int]:rtype: int"""# 转换思维:统计每个数字的总点数,生成一个数组sums[x] = x*count(x)# 接着,类似于打家劫舍问题,取不相邻的元素,使元素的和最大# 设dp[i]为遍历到i的最优解,dp[i] = max(dp[i-1],dp[i-2]+sums[i])# 生成sums数组(先找到nums[i]的最大值,用它作为sums数组的最大边界)max_num = max(nums)sums = [0] * (max_num+1) #初始化for num in nums:sums[num] += num# 动态规划求解if len(sums) == 1:return 0dp = [0,sums[1]]#dp = [sums[0],max(sums[0],sums[1])]for i in range(2,len(sums)):dp.append(max(dp[i-1],dp[i-2]+sums[i]))return dp[len(sums)-1]

优化技巧:

1、滚动变量替代dp数组

class Solution(object):def rob(self, nums):n = len(nums)if n==1:return nums[0]# 滚动变量优化空间,不需要整个dp数组pre, cur = nums[0],max(nums[0],nums[1]) #dp = [nums[0],max(nums[0],nums[1])]for i in range(2,n):pre, cur = cur, max(cur, pre+nums[i])#dp.append(max(dp[i-1],dp[i-2]+nums[i]))return cur

可以理解为先计算temp = max(cur, pre + nums[i]),然后让pre=cur,再让cur=temp。

最长回文子串:

(1)定义状态:dp[i][j]表示字符串从第i个字符到第j个字符是否为回文字符串。

(2)状态转移方程:

往子问题方向拆分——如果dp[i][j]是回文子串,那么两端的字符必定相等,而且中间的字符串(如果有)也应该是回文子串。即

dp[i][j] = (s[i]==s[j])&&((j==i+1)or dp[i+1][j-1])

(3)初始条件:

只有一个字符,dp[i][i]=True

则,可以总结出:dp[i][i]=True

                              dp[i][j] = (s[i]==s[j])&& ((j==i+1)or dp[i+1][j-1])

迭代法的状态转移:判断首尾相等后,每个位置的状态和它的左下角的状态有关

class Solution(object):def longestPalindrome(self, s):""":type s: str:rtype: str"""n = len(s)if n<=1:return s# 初始化动态规划表dp = [[False]*n for _ in range(n)]# 初始条件:所有长度为1的子串都是回文for i in range(n):dp[i][i] = Truemax_len = 1start = 0 #追踪最长回文子串的起始位置# dp[i][j] = (s[i]==s[j])&& ((j==i+1)|| dp[i+1][j-1] )for j in range(1,n): #右指针,子区间的右边界,从1到n-1for i in range(0,j): #左指针,子区间的左边界,从0到j-1if s[i]==s[j]: #如果左右边界相等if (j==i+1) or (dp[i+1][j-1]): #如果没有中间部分或者中间部分也是回文子串dp[i][j] = True #标记length = j-i+1if length>max_len: #看需不需要更新max_len=lengthstart=i return s[start:start+max_len]

[False] * n 借助列表乘法操作,将包含单个 False 的列表重复 n 次,从而生成一个长度为 n 且所有元素都为 False 的一维列表。

_ 是 Python 里的一个惯用变量名,通常用于表示一个临时的、不会被使用的变量。

s[start:start+max_len] 是 Python 中用于字符串切片操作(左闭右开)的表达式。它的作用是从字符串 s 中提取一个子字符串,该子字符串从索引 start 开始,到索引 start + max_len - 1 结束。

高阶理解:

(有向无环图,状态可转移;空间换时间)

将节点抽象,关系用边表示,用人脑简单求一次拓扑排序,

如果有环,则一定不是动态规划

也和数据范围有关,数据量太大,无法映射到数组中,就不是动态规划

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

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

相关文章

redis高级数据结构Stream

文章目录 背景stream概述消息 ID消息内容常见操作独立消费创建消费组消费 Stream弊端Stream 消息太多怎么办?消息如果忘记 ACK 会怎样?PEL 如何避免消息丢失?分区 Partition Stream 的高可用总结 背景 为了解决list作为消息队列是无法支持消息多播问题&#xff0c;Redis5.0…

ASP.NET Core WebSocket、SignalR

目录 WebSocket SignalR SignalR的基本使用 WebSocket WebSocket基于TCP协议&#xff0c;支持二进制通信&#xff0c;双工通信。性能和并发能力更强。WebSocket独立于HTTP协议&#xff0c;不过我们一般仍然把WebSocket服务器端部署到Web服务器上&#xff0c;因为可以借助HT…

多路文件IO

一、思维导图

在CT107D单片机综合训练平台上,8个数码管分别单独依次显示0~9的值,然后所有数码管一起同时显示0~F的值,如此往复。

题目&#xff1a;在CT107D单片机综合训练平台上&#xff0c;8个数码管分别单独依次显示0~9的值&#xff0c;然后所有数码管一起同时显示0~F的值&#xff0c;如此往复。 延时函数分析LED首先实现8个数码管单独依次显示0~9的数字所有数码管一起同时显示0~F的值&#xff0c;如此往…

小红书提出新面部视频交换方法DynamicFace,可生成高质量且一致的视频面部图像。

DynamicFace是一种新颖的面部视频交换方法&#xff0c;旨在生成高质量且一致的视频面部图像。该方法结合了扩散模型的强大能力和可插拔的时间层&#xff0c;以解决传统面部交换技术面临的两个主要挑战&#xff1a;在保持源面部身份的同时&#xff0c;准确传递目标面部的运动信息…

2025.2.9机器学习笔记:PINN文献阅读

2025.2.9周报 文献阅读题目信息摘要Abstract创新点网络架构实验结论缺点以及后续展望 文献阅读 题目信息 题目&#xff1a; GPT-PINN:Generative Pre-Trained Physics-Informed Neural Networks toward non-intrusive Meta-learning of parametric PDEs期刊&#xff1a; Fini…

天津三石峰科技——汽车生产厂的设备振动检测项目案例

汽车产线有很多传动设备需要长期在线运行&#xff0c;会出现老化、疲劳、磨损等 问题&#xff0c;为了避免意外停机造成损失&#xff0c;需要加装一些健康监测设备&#xff0c;监测设备运 行状态。天津三石峰科技采用 12 通道振动信号采集卡&#xff08;下图 1&#xff09;对…

CSGHub高效管理|解锁DeepSeek R1蒸馏模型 :高效推理的新选择

在大模型的新时代&#xff0c;如何在保持高推理能力的同时降低计算成本&#xff0c;已经成为企业和开发者们关注的核心问题。 你是否也在寻找一个既强大又高效的AI模型&#xff1f; DeepSeek R1&#xff0c;作为目前领先的AI模型之一&#xff0c;不仅推出了强大的671B参数旗舰模…

来自国外的实用软件 ,已接触所有限制!

今天我给大家带来了一款超棒的全自动抠图软件&#xff0c;真的是一个来自国外的宝藏工具&#xff01;而且好消息是&#xff0c;它现在完全解除了限制&#xff0c;可以无限畅快地使用了。 Teorex PhotoScissors 抠图软件 这款软件特别贴心&#xff0c;根本不需要安装&#xff0…

win32汇编环境,结构体的使用示例一

;运行效果 ;win32汇编环境,结构体的使用示例一 ;举例说明结构体的定义&#xff0c;如何访问其中的成员&#xff0c;使用assume指令指向某个结构体&#xff0c;利用偏移得到成员值等 ;直接抄进RadAsm可编译运行。重要部分加备注。 ;下面为asm文件 ;>>>>>>>…

Ai无限免费生成高质量ppt教程(deepseek+kimi)

第一步&#xff1a;打开deepseek官网&#xff08;DeepSeek) 1.如果deepseek官网网络繁忙&#xff0c;解决方案如下&#xff1a; (1)使用easychat官网&#xff08;EasyChat&#xff09;使用deepseek模型&#xff0c;如图所示&#xff1a; &#xff08;2&#xff09;本地部署&…

C#常用集合优缺点对比

先上结论&#xff1a; 在C#中&#xff0c;链表、一维数组、字典、List<T>和ArrayList是常见的数据集合类型&#xff0c;它们各有优缺点&#xff0c;适用于不同的场景。以下是它们的比较&#xff1a; 1. 一维数组 (T[]) 优点&#xff1a; 性能高&#xff1a;数组在内存中…

大数据项目2a:基于spark的电影推荐和分析系统设计与实现

1、项目目的 本项目的目的是设计并实现一个基于Spark的电影推荐系统&#xff0c;以应对大数据环境下电影推荐服务的挑战。通过整合电影、评分和用户数据集&#xff0c;并利用SparkSql框架进行高效处理&#xff0c;系统能够为用户提供个性化的电影推荐。项目采用多种先进技术&…

CANoe工具使用技巧 --- 如何使用 “on ethernetPacket “事件处理程序

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

数据库5(MySQL版)

作业要求 触发器 mysql> create trigger after_order_insert -> after insert on orders -> for each row -> update goods set num num - new.onum where gid new.gid; mysql> create trigger after_order_delete -> after delete on or…

【异常解决】在idea中提示 hutool 提示 HttpResponse used withoud try-with-resources statement

博主介绍&#xff1a;✌全网粉丝22W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

浅析Ruby类污染及其在Sinatra框架下的利用

和JavaScript中的原型链污染类似&#xff0c;Ruby中也存在类似的概念——类污染&#xff0c;两者都是对象进行不安全的递归合并导致的。 网上也没有相关的分析文章&#xff0c;只有下面这篇文章应该是第一次谈到这个问题 Class Pollution in Ruby: A Deep Dive into Exploiti…

SamWaf开源轻量级的网站应用防火墙(安装包),私有化部署,加密本地存储的数据,易于启动,并支持 Linux 和 Windows 64 位和 Arm64

一、SamWaf轻量级开源防火墙介绍 &#xff08;文末提供下载&#xff09; SamWaf网站防火墙是一款适用于小公司、工作室和个人网站的开源轻量级网站防火墙&#xff0c;完全私有化部署&#xff0c;数据加密且仅保存本地&#xff0c;一键启动&#xff0c;支持Linux&#xff0c;Wi…

14vue3实战-----获取用户信息和用户的菜单树信息

14vue3实战-----获取用户信息和用户的菜单树信息 1.获取用户信息1.1封装接口1.2优化 2.获取用户的菜单树信息 1.获取用户信息 1.1封装接口 后端有根据id获取用户信息的接口&#xff0c;前端需要把该接口封装一下: service/login/login.ts&#xff1a; import hyRequest from…

洛谷算法1-3 暴力枚举

目录 1 P2241统计方形 2 三连击 3 选数 4 P1088 [NOIP2004 普及组] 火星人 5 P3799 小 Y 拼木棒 排列组合 6 P2392 kkksc03考前临时抱佛脚 7 P2036 [COCI2008-2009 #2] PERKET 1 P2241统计方形 思路&#xff1a; 本题中&#xff0c;矩阵数量正方形数量长方形数量&#xff0…