- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
本文分享自华为云社区《五大基础算法--动态规划法》,作者: 大金(内蒙的)。
动态规划法,和分治法极其相似。区别就是,在求解子问题时,会保存该子问题的解,后面的子问题求解时,可以直接拿来计算。
对于一个规模为n的问题,将其分解为k个规模较小的子问题(阶段),按顺序求解子问题,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,通过决策求得局部最优解,依次解决各子问题。最后可以通过简单的判断,得到原问题的解。
阶段:求解第n个子问题称为第n个阶段。动态规划是按照顺序去求解子问题的,这里子问题的求解顺序很重要。
状态:在求解第n个阶段时,已求解n-1个阶段的解,称为状态。
决策:在求解第n个阶段时,根据状态和计算规则,可以得到第n个阶段时解。
动态规划法所能解决的问题一般具有以下几个特征:
该问题可以分解为若干个规模较小的问题,即该问题具有最优子结构性质。
该问题的规模缩小到一定的程度就可以容易地解决
利用该问题分解出的子问题的解可以合并为该问题的解;
当计算出某个子问题的解时,后续多个问题都需要计算该子问题的解,所以在计算某个子问题的解,将其保存,就节省了分治法重复计算的时间。
很多博客都说什么状态转移方程,感觉说的很高大上,一般解题上来就是状态转移方程是xxxx,代码是xxxx,翻译下是什么意思呢?
在求解第n个子问题的时候,通过已求解n-1个阶段的解和计算规则,可以得到第n个阶段时解。
即是最新的状态=目前的状态+决策。
很多题目解题的时候都说初始化,这并不是动态规划法的步骤。应该正确的去理解这些操作。动态规划在划分子问题求解顺序时,基本是先求解易求解最小的子问题,在由这些已经求解的阶段+计算规则,就能直接求得第n阶段的解。所以初始化的含义是,求得初始阶段的解。
一般题目会说边界是啥,可以理解为怎么判断所有的子问题已经求解结束了。正常人也不会写while(true)吧,你总得让程序结束,判断你已经解决好这个问题了。
将一个问题分解为多个子问题,需要注意子问题解决的顺序,应该先求解易求解的子问题,且后续的阶段可以通过前面的阶段+决策得到。
通过得到的规律,写出状态转移方程。
第n阶段=当前状态+决策(前n个阶段解和计算规则)
将最先算的阶段计算出来,中间阶段通过状态转移方程计算状态,直到所有阶段计算结束。
所有阶段计算结束,可以通过简单的统计,例如Max,Min等遍历阶段的值,得到最后的解。
好记性不如烂笔头,有一些适用动态规划法的问题,可以帮我们不断强化的解题思想。在解决问题时,希望大家可以注意判断题目的解决思路,看是否符合动态规划法的四个特征,这样不断强化,才能将算法掌握。
https://leetcode-cn.com/problems/longest-palindromic-substring/solution/dong-tai-gui-hua-fa-qiu-jie-kan-bu-dong-octkt/
//动态规划法两个基本要素:最优子结构性质和子问题重叠性质。
//很多答案写了初始化和边界条件,个人认为你要分清楚他的目的是什么。
//很多初始化和边界条件,是因为状态转移方程,是需要初始化的子问题的解,从而避免重复计算,说白了还是子问题重叠和最优子结构问题。
//我们应该注重某一个问题的重叠子问题分解和状态最优的决策分析。
//解题思路:
//计算某个字符串时, 如果它首尾字符相等,则它是不是回文,取决于去掉头尾之后的字符串是否为回文串。
// 如果它首尾字符不相等,则它一定不是回文
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
// 特判
if (len < 2){
return s;
}
int maxLen = 1;
int begin = 0;
// 1. 状态定义
// dp[i][j] 表示s[i...j] 是否是回文串,现在表示全部为0,不是回文串
boolean[][] dp = new boolean[len][len];
char[] chars = s.toCharArray();
// 2. 子问题计算顺序:先计算短字符串,在计算长字符串,同时根据已求得的短字符串或者计算规则,可以得到长字符串的解。
// 注意:s表示计算的元素顺序。
// 0 1 2 3 4
// 0 xx s1 s2 s4 s7
// 1 xx s3 s5 s8
// 2 xx s6 s9
// 3 xx s10
// 4 xx
// 为什么这么写呢,因为你要保证保证计算某个元素时,通过状态转移方程能得到左上角元素的dp[][]。
// 填表规则:先一列一列的填写,再一行一行的填,保证计算某个元素时,它左上方的单元格已经被计算出了结果
// 填表规则:当然你也可以由左往右一行一行写,这样也能保证计算某个元素时,它左上方的单元格已经被计算出了结果
for (int j = 1;j < len;j++){
for (int i = 0; i < j; i++) {
// 头尾字符不相等,不是回文串
if (chars[i] != chars[j]){
dp[i][j] = false;
}else {
// 相等的情况下
// 因为考虑头尾去掉以后没有字符剩余,或者剩下一个字符的时候,肯定是回文串
if (j - i -1 <= 1){
dp[i][j] = true;
}else {
// 头尾相等,中间有大于1个元素,这个时候,我们无法直接判断他是不是回文,但是我们可以通过状态转移方程去判断
// 其实这个就是在计算s8这个元素时,我们无法判断dp[1][4]在1和4位元素相等时候,整个字符串是否是回文。
// 所以要通过s4去判断,s4是回文,s8就是。s4不是,那s8就不是。
dp[i][j] = dp[i + 1][j - 1];
}
}
// 只要dp[i][j] == true 成立,表示s[i...j] 是否是回文串
// 此时更新记录回文长度和起始位置
if (dp[i][j] && (j - i + 1 > maxLen)){
maxLen = j - i + 1;
begin = i;
}
}
}
// 3. 初始化
// 很多答案写了这个,这一步,我们细想,其实完全没有必要。
// 因为主对角线,值是可以直接判断出来的。
// 而且在求解过程中,我们的状态转移方程不会用到这个值。因为只有主对角线会用到这几个值。
// 而且单个元素的子问题解,我们并不需要。
// 所以,即使我这步初始化放到计算之后,甚至是直接去掉,也完全不影响结果。大家可以自己试一下
// for (int i = 0; i < len; i++) {
// dp[i][i] = true;
// }
// 4. 返回值
return s.substring(begin,begin + maxLen);
}
}
在 JavaScript 中,我们可以动态创建 元素并附加到 部分,以便为大量元素应用 CSS 规则。 这种方法的优点或缺点是什么? 如果它确实提供了与元素上的 javascript 迭代相比的性
我有这个代码 import "./HTTPMethod.dart"; import '../../DataModel/DataModel.dart'; mixin RouterMixin { HT
哪些 OLAP 工具支持动态、动态地创建维度或层次结构? 例如,层次结构将成员定义为:“前 5 名”、“前 6-10 名”、“其他”... 计算成员是通常的答案,我正在寻找不同的东西。计算器的问题。成
我正在 CakePHP 中创建一个“表单编辑器”。 该界面允许用户选择要应用于字段的验证,例如数字、电子邮件等 因此,我需要根据用户输入为模型动态创建验证。为此,我可以使用验证对象:https://b
这是一个场景: 我有一个Web服务,我们将其称为部署在tomcat(轴)上的StockQuoteService。通过此 Web 服务公开了 getStockQuote() 方法。 现在,我想构建一个
我正在尝试从服务器获取 JSON 响应并将其输出到控制台。 Future login() async { var response = await http.get( Uri.
我从另一个问题中得到了这段代码(感谢 chunhunghan)。我需要创建一个登录屏幕,并尝试根据服务器发回给我的响应来验证用户凭据,但是每次我尝试运行代码时,它都会给我“未处理的异常:Interna
当我在“Dart”主程序中运行它时,一切正常,并且我得到了一个与会者列表。但是,当我在我的 Flutter 应用程序中调用它时,出现错误: flutter:“List”类型不是“List>”类型的子类
本文实例为大家分享了js实现验证码动态干扰的具体代码,供大家参考,具体内容如下 效果一 效果二 代码一 ?
目前我正在为我的网站使用 No-Ip,我想使用 cloudflare 来抵御 ddos 和机器人程序。我注意到您需要一个用于 cloudflare 的域。我还搜索了网络,发现了一个叫做 cloud
有没有办法在 Excel VBA 中构建动态 if 语句?基本上我正在尝试创建一个参数化计算,用户将能够输入不同的变量,即 变量 1 “变量 2” “变量 3” 在这种情况下 变量 1 是单元格引用
大家好, 请查看上面的图片,我有两张 table 。在下面代码的第一个表中,我得到了这种格式。 但我想像 Table2 那样格式化,每个合并单元格中的行数是动态的,而且不一样。 有没有办法像table
如何根据我添加的 View 修改标题部分的高度?heightForHeaderInSection在 viewForHeaderInSection 之前被调用我不知道 View 大小,直到我创建它。 最
是否存在在运行时生成 AST/解析树的解析器?有点像一个库,它会接受一串 EBNF 语法或类似的东西并吐出数据结构? 我知道 antlr、jlex 和他们的同类。他们生成可以做到这一点的源代码。 (喜
我在持有汽车制造商的表格上有一个 MultipleChoiceField。我想将我的汽车数据库过滤到已检查的品牌,但这会导致问题。如何动态获取所有 Q(make=...) 语句? 我如何开始:['va
$end = preg_replace($pattern, $replacement, $str); 如何使替换字符串 $replacement 随 $str 中的每次匹配而变化?例如,我想用关联的图
我正在编写一个 VBA 程序,用于过滤表中的值。我试图使其成为一个适用于您提供的所有表格的通用程序。在我的程序中,我必须设置它正在过滤的表的范围:Set rng = dataSheet.Range("
我正在循环一个元素数组,并且我想使用给定的模板递归地显示该元素 然后在该模板内使用带有切换功能的按钮来显示/隐藏给定元素的Child的更深级别模板(Child也是一个元素) 这是我的模板
从客户端(html)发送表单,服务器端通过选择选项之一决定运行哪个函数。 const decideWho = (form) => { const choice = form.choice; c
我有一个具有以下属性的按钮: circle_normal.xml(在 res/drawable 中) circle.xml(在 res/drawable 中)
我是一名优秀的程序员,十分优秀!