算法篇——动态规划

核心思想:

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

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

比如:斐波那契数列问题中,递归求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 n

        self.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 0
        dp = [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] = True
        max_len = 1
        start = 0 #追踪最长回文子串的起始位置

       # dp[i][j] = (s[i]==s[j])&& ((j==i+1)|| dp[i+1][j-1] )
        for j in range(1,n): #右指针,子区间的右边界,从1到n-1
            for i in range(0,j): #左指针,子区间的左边界,从0到j-1
                if s[i]==s[j]: #如果左右边界相等
                    if (j==i+1) or (dp[i+1][j-1]): #如果没有中间部分或者中间部分也是回文子串
                        dp[i][j] = True #标记

                        length = j-i+1
                        if length>max_len: #看需不需要更新
                            max_len=length
                            start=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 结束。

高阶理解:

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

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

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

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

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

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

相关文章

一个基于ESP32S3和INMP441麦克风实现音频强度控制RGB灯带律动的代码及效果展示

一个基于ESP32S3和INMP441麦克风实现音频强度控制RGB灯带律动的代码示例&#xff0c;使用Arduino语言&#xff1a; 硬件连接 INMP441 VCC → ESP32的3.3VINMP441 GND → ESP32的GNDINMP441 SCK → ESP32的GPIO 17INMP441 WS → ESP32的GPIO 18INMP441 SD → ESP32的GPIO 16RG…

零基础学习书生.浦语大模型--基础岛

第二关:玩转书生[多模态对话]和[AI搜索]产品 任务一&#xff1a;使用MindSearch 任务二&#xff1a;尝试使用书生.浦语 尝试让其写一段Self-Attention网络模块代码 import torch import torch.nn as nn import torch.nn.functional as Fclass SelfAttention(nn.Module):def _…

AWS Fargate

AWS Fargate 是一个由 Amazon Web Services (AWS) 提供的无服务器容器计算引擎。它使开发者能够运行容器化应用程序&#xff0c;而无需管理底层的服务器或虚拟机。简而言之&#xff0c;AWS Fargate 让你只需关注应用的容器本身&#xff0c;而不需要管理运行容器的基础设施&…

启明星辰发布MAF大模型应用防火墙产品,提升DeepSeek类企业用户安全

2月7日&#xff0c;启明星辰面向DeepSeek等企业级大模型业务服务者提供的安全防护产品——天清MAF&#xff08;Model Application Firewall&#xff09;大模型应用防火墙产品正式发布。 一个新赛道将被开启…… DeepSeek的低成本引爆赛道规模 随着DeepSeek成为当前最热的现象级…

Excel大数据量导入导出

github源码 地址&#xff08;更详细&#xff09; : https://github.com/alibaba/easyexcel 文档&#xff1a;读Excel&#xff08;文档已经迁移&#xff09; B 站视频 : https://www.bilibili.com/video/BV1Ff4y1U7Qc 一、JAVA解析EXCEL工具EasyExcel Java解析、生成Excel比较…

Coze(扣子)+ Deepseek:多Agents智能体协作开发新范式

前言 在当今数字化浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;技术的迅猛发展正深刻改变着我们的生活和工作方式。从智能语音助手到自动化流程机器人&#xff0c;AI 的应用无处不在&#xff0c;为我们提供了更加便捷、高效的服务。然而&#xff0c;对于非专业人士来…

Spring AI -使用Spring快速开发ChatGPT应用

前言 Spring在Java生态中一直占据大半江山。最近我发现Spring社区推出了一个Spring AI项目&#xff0c;目前该项目还属于Spring实验性项目&#xff0c;但是我们可以通过该项目&#xff0c;可以非常快速的开发出GPT对话应用。 本篇文章将会对SpringAI进行简单的介绍和使用&#…

Unity项目接入xLua的一种流程

1. 导入xlua 首先导入xlua&#xff0c;这个不用多说 2. 编写C#和Lua交互脚本 基础版本&#xff0c;即xlua自带的版本 using System.Collections; using System.Collections.Generic; using UnityEngine; using XLua; using System; using System.IO;[Serializable] public…

LM Studio 部署本地大语言模型

一、下载安装 1.搜索&#xff1a;lm studio LM Studio - Discover, download, and run local LLMs 2.下载 3.安装 4.更改成中文 二、下载模型(软件内下载) 1.选择使用代理&#xff0c;否则无法下载 2.更改模型下载目录 默认下载位置 C:\Users\用户名\.lmstudio\models 3.搜…

route 与 router 之间的差别

简述&#xff1a; router&#xff1a;主要用于处理一些动作&#xff0c; route&#xff1a;主要获得或处理一些数据&#xff0c;比如地址、参数等 例&#xff1a; videoInfo1.vue&#xff1a; <template><div class"video-info"><h3>二级组件…

DeepSeek-V2 论文解读:混合专家架构的新突破

论文链接&#xff1a;DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model 目录 一、引言二、模型架构&#xff08;一&#xff09;多头部潜在注意力&#xff08;MLA&#xff09;&#xff1a;重塑推理效率&#xff08;二&#xff09;DeepSeekM…

Android修行手册-五种比较图片相似或相同

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材…

力扣--链表

相交链表 法一&#xff1a; 把A链表的节点都存HashSet里&#xff0c;遍历B链表找相同的节点 法二&#xff1a; 把A、B指针都移到末尾&#xff0c;再同时往回走&#xff0c;每次往回走都比较 当前节点的下一节点&#xff08;a.next b.next ?)是否相同&#xff0c;当不相同…

只需两步,使用ollama即可在本地部署DeepSeek等常见的AI大模型

只需两步&#xff0c;使用ollama即可在本地部署DeepSeek等常见的AI大模型 1.下载ollama,进入ollama官网即可将ollama下载到本地&#xff0c;之后按照提示安装ollama。 https://ollama.com/download/windows 2.安装大模型 进入ollama官网模型页面&#xff0c;找到所需的模型及版…

Qt修仙之路2-1 仿QQ登入 法宝初成

widget.cpp #include "widget.h" #include<QDebug> //实现槽函数 void Widget::login1() {QString userusername_input->text();QString passpassword_input->text();//如果不勾选无法登入if(!check->isChecked()){qDebug()<<"xxx"&…

大模型deepseek-r1 本地Open WebUI部署详解

一、Open WebUI简介 Open WebUI是一个用户友好的Web界面&#xff0c;专为本地大语言模型&#xff08;LLMs&#xff09;设计。它支持多种模型&#xff0c;包括Ollama和OpenAI兼容的API&#xff0c;并允许用户通过图形界面轻松调试和调用模型。Open WebUI的功能丰富&#xff0c;…

免费windows pdf编辑工具Epdf

Epdf&#xff08;完全免费&#xff09; 作者&#xff1a;不染心 时间&#xff1a;2025/2/6 Github: https://github.com/dog-tired/Epdf Epdf Epdf 是一款使用 Rust 编写的 PDF 编辑器&#xff0c;目前仍在开发中。它提供了一系列实用的命令行选项&#xff0c;方便用户对 PDF …

大模型训练(7):集合通信与通信原语

0 背景 分布式训练过程中设计到许多通信上的操作&#xff0c; 每个操作有其不同的术语并且有所区别&#xff0c;这里将其用简单的例子和描述总结一下&#xff0c;方便理解。 集合通信&#xff08;Collective Communications&#xff09;是一个进程组的所有进程都参与的全局通…

线程上下文-ThreadLocal原理

ThreadLocal主要作用&#xff1a;为每个线程提供独立的变量副本&#xff0c;实现线程间的数据隔离&#xff0c;从而避免多线程环境下的资源共享冲突。 原理 ThreadLocal有个内部类 ThreadLocalMap&#xff0c;顾名思义是个Map结构&#xff1a;key为 ThreadLocal实例&#xff0…

第31周:文献阅读

目录 摘要 Abstract 文献阅读 问题引入 研究背景 研究动机 创新点 动态预训练方法&#xff08;DynPT&#xff09; 深度循环神经网络&#xff08;DRNN&#xff09; 传感器选择 方法论 时间序列的动态预训练 异构传感器数据的DRNN 基于稀疏度的传感器过滤 实验研…