动态规划(1):基本思路以及步骤

2024-02-14 14:08

本文主要是介绍动态规划(1):基本思路以及步骤,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基本思想

动态规划是针对一类求最优解的问题的算法, 其核心是将一个问题分解成为若干个子问题(这里对应下文的子问题使用条件), 部分类似于分治的思想(不懂得可以参考归并排序), 通过求每一次的最优决策, 来得到一个最优解。在这里最重要的就是子问题的思想。

另一种理解方式数是DP的核心是加法原理(下文的人人为我形递归)和乘法原理(下文的我为人人形递归), 通过这两个原理, 在当状态的前有限多个状态中找到最优解来求得当前状态, 而对于前一个或者前几个状态采用同样的方法知道求出边界状态,这种方法最恶心的就是边界状态

在学会搜索之后, 最简单入门DP的方法就是记忆话搜索, 但是后来会发现大多数DP题目因为时间和内存的限制并不能使用递归(函数的递归调用会占用栈内存, 另外函数的递归调用也将占用大量的时间)

子问题解决法的适用条件

需同时满足一下三点:

1.具有相同的子问题:我们必须保证我们分割成的子问题也能按照相同的方法分割成更小的自问题, 并这些自问题的最终分割情况是可以解决的。

2.满足最优子结构:就是一个决策的子决策也是最优的

3.无后效性:这是DP中最重要的一点, 他要求每个子问题的决策不能对后面其他未解决的问题产影响, 如果产生就无法保证决策的最优性, 这就是无后效性。往往需要我们找到一个合适的状态。
··这条非常重要
··这条非常重要
··这条非常重要
举个例子:我们在LIS中先求前M项的LIS, 然后依次向后求, 直到str.len, 这就是因为我们在求前M项的过程中, 对(M + 1)→(str.len)并无影响。消除后效性的例子等等会单开一片博客来讲。

常用的解题步骤

前两天刚刚被大牛虐过DP, 姑妄言之:

第一步:确定子问题。 在这一步重点是分析那些变量是随着问题规模的变小而变小的, 那些变量与问题的规模无关。
第二步:确定状态:根据上面找到的子问题来给你分割的子问题限定状态
第三步:推到出状态转移方程:这里要注意你的状态转移方程是不是满足所有的条件, 注意不要遗漏。
第四步:确定边界条件:先根据题目的限制条件来确定题目中给出的边界条件是否能直接推导出, 如果不行也可以尝试从边界条件反推(举个例子:a(n)→a(2)有递推关系, 但是a(2)→a(1)不符合上述递推关系, 我们就可以考虑用a(1)来倒推出a(2), 然后将递推的终点设置为a(2));
第五步:确定实现方式:这个依照个人习惯 就像是01背包的两层for循环的顺序
第六步:确定优化方法:很多时候你会发现走到这里步的时候你需要返回第1步重来。首先考虑降维问题(优化内存), 优先队列、四边形不等式(优化时间)等等。

常用方法

以下是方法, 但是不要局限在这里, 方法是无限的

(1)模型匹配法:熟练记忆并且理解LIS、LCS、01背包、完全背包、区间模型、树状模型。基本就是将原模型加以变化后加以套用

(2)三要素法:
·······先确定阶段:如数塔问题, 先确定当前选的是第几层。
·······先确定状态:这是最常用的绝大多数的DP都是这么做的。
·······先确定决策:背包问题(选还是不选第i种物品)
这是个经验问题, 然而我还没有这种经验。

(3)寻找规律法:从小的状态开始推, 耐心找规律, 或者可以在本地暴力打表, 暴力出奇迹, 不打2、3页那都不叫打表,几年省赛彻底领悟了,不想说啥。

(4)边界条件法: 一般边界时容易导出状态关系的地方

(5)增加约束条件法:这条就对应着上文的消除后效性,以后的博客会有例题

这篇关于动态规划(1):基本思路以及步骤的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/708703

相关文章

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

C#连接SQL server数据库命令的基本步骤

《C#连接SQLserver数据库命令的基本步骤》文章讲解了连接SQLServer数据库的步骤,包括引入命名空间、构建连接字符串、使用SqlConnection和SqlCommand执行SQL操作,... 目录建议配合使用:如何下载和安装SQL server数据库-CSDN博客1. 引入必要的命名空间2.

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

创建Java keystore文件的完整指南及详细步骤

《创建Javakeystore文件的完整指南及详细步骤》本文详解Java中keystore的创建与配置,涵盖私钥管理、自签名与CA证书生成、SSL/TLS应用,强调安全存储及验证机制,确保通信加密和... 目录1. 秘密键(私钥)的理解与管理私钥的定义与重要性私钥的管理策略私钥的生成与存储2. 证书的创建与

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

IDEA中新建/切换Git分支的实现步骤

《IDEA中新建/切换Git分支的实现步骤》本文主要介绍了IDEA中新建/切换Git分支的实现步骤,通过菜单创建新分支并选择是否切换,创建后在Git详情或右键Checkout中切换分支,感兴趣的可以了... 前提:项目已被Git托管1、点击上方栏Git->NewBrancjsh...2、输入新的分支的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

python删除xml中的w:ascii属性的步骤

《python删除xml中的w:ascii属性的步骤》使用xml.etree.ElementTree删除WordXML中w:ascii属性,需注册命名空间并定位rFonts元素,通过del操作删除属... 可以使用python的XML.etree.ElementTree模块通过以下步骤删除XML中的w:as

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试