近期重新复习了一下动态规划(DP),整理了一些经典的动态规划问题,接下来我就给大家介绍一下,其中包括最大连续子序列的和,最长递增子序列,最长公共子序列,最长公共子串。(如果不清楚DP的概念可以查阅网上的资料,我就不重复了。。。)
首先,我们要知道子序列和子串的区别,子序列可以是不连续的,而子串必须是一个连续的序列。对于最大连续子序列的和,最长递增子序列这两个问题属于一维的DP,最长公共子序列,最长公共子串属于二维的DP问题。
1. 最大连续子序列的和
对于这道题,我们可以理解成找出一个子串,使它的和最大。 解决这个问题我们可以设定两个变量current和global,current保存当前的最大值,global保存全局的最大值。假设给定了一个数组nums[],从中找出一个子串,使子串的和最大(如果是字符串基本原理也一样)。代码如下:
public int maxSubArray(int[] nums) {
if(nums == null || nums.length == 0)
return 0;
int cur = nums[0];
int global = nums[0];
for(int i = 1; i < nums.length; i++) {
cur = Math.max(nums[i], cur + nums[i]);
global = Math.max(global, cur);
}
return global;
}
2. 最长递增子序列(LIS)
给定一个数组,找出最长的递增序列。例如给定{10, 9, 2, 5, 3, 7, 101},{2,3,7,101}是最长的子序列,此时return 4。这道题也是一个一维的DP问题。假设给我们一个数组nums[],首先我们设定一个辅助数组result[],长度为nums.length,初始化所有的值为1,代表长度最小为1。并且我们设定一个全局的变量max始终记录最大的长度。首先我们从数组的第二个元素开始,依次与它前面的元素比较。如果当前元素nums[i] > nums[j](i > j),此时的递推公式为result[i] = max(result[i], result[j] + 1), 并且比较result[i]与max的值,如果result[i] > max, 令max = result[i]. 代码如下:
public int lengthOfLIS(int[] nums) {
if(nums == null || nums.length == 0) return 0;
int[] result = new int[nums.length];
Arrays.fill(result, 1);
int max = 1;
for (int i = 1; i < nums.length; i++) {
for(int j = 0; j < i; j++){
//如果是非递减序列 if(nums[i] >= nums[j])
if(nums[i] > nums[j]) {
result[i] = Math.max(result[i], result[j] + 1);
if(result[i] > max)
max = result[i];
}
}
}
return max;
}
3. 最长公共子序列 和最长公共子串
最长公共子序列和最长公共子串问题都是一个二维的DP问题,给定两个字符串s, t, 从两个字符串中找到最长的一个公共子序列或子串。这两个问题都很大的相似之处,因为我们通过对比,一起解决这两个问题。假设字符串s="acdb", t ="abdc"。第一次比较s0 == t0, 此时result[i][j] = 1, 接下来我们需要比较s1 是否等于t1,此时s1 != t1, 如果是公共子序列,我们需要保存一个最大值,result[i][j] = Math.max(result[i-1][j], result[i][j-1]), 因为此时的子序列并没有中断,如果后面还可以继续匹配,长度要在此基础上增加; 如果是公共子串, 我们只需要维护一个全局的变量,记录每次匹配是的最大值,因为子串必须是连续的,如果当前比较不相等,我们仅需要得到以前的可以匹配的子串的最大长度即可。代码如下
最大公共子序列:
public static int lonestCommenSubsquence(String s, String t) {
int[][] result = new int[s.length()+1][t.length()+1];
for (int i = 1; i <= s.length(); i ++)
for (int j = 1; j <= t.length(); j ++) {
if(s.charAt(i - 1) == t.charAt(j - 1)){
result[i][j] = result[i - 1][j - 1] + 1;
}else{
result[i][j] = Math.max(result[i-1][j], result[i][j-1]);
}
}
return result[s.length()][t.length()];
}
最大公共子串:
public static int longestCommenSubstring(String s, String t) {
int m = s.length();
int n = t.length();
int[][] result = new int[m+1][n+1];
int max = 0;
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++) {
if(s.charAt(i - 1) == t.charAt(j - 1)){
result[i][j] = result[i - 1][j - 1] + 1;
if(result[i][j] > max)
max = result[i][j];
}
}
return max;
}
以上都是DP最基本的问题,也是我自己对DP问题的一点理解,本人能力有限,其中难免有不恰当之处,希望大家可以指出来,共同进步。
分享到:
相关推荐
动态规划经典题目总结 动态规划是算法设计中的一种...动态规划经典题目总结中包括了多种经典的动态规划问题,解决这些问题需要使用动态规划的方法,并且需要根据问题的具体情况选择合适的状态转移方程和优化方法。
总结来说,基于LINGO的动态规划法是解决复杂优化问题的有效工具,尤其适合教学和实践场景。通过学习和应用,不仅可以理解动态规划的基本概念,还能掌握使用优化软件解决实际问题的方法,这对于提升学生在交通工程等...
### 动态规划经典教程及题目解析 #### 一、动态规划概述 动态规划(Dynamic Programming,简称DP)是一种在计算机科学与数学中用于解决最优化问题的有效算法思想。它通过对问题进行分解,并利用子问题的解来构建...
本篇文章将深入探讨如何运用LINGO来解决动态规划问题,通过具体的案例分析,我们将了解LINGO在动态规划中的应用方法和步骤。 ### 动态规划与LINGO 动态规划是一种用于解决多阶段决策过程中的最优化问题的方法,其...
数据结构动态规划算法总结 动态规划是一种重要的算法思想,广泛应用于经济管理、生产调度、工程技术和最优控制等方面。动态规划是解决多阶段决策过程的优化问题的数学方法,由美国数学家R.E.Bellman等人在20世纪50...
《动态规划算法实验》实验报告主要探讨了两个经典动态规划问题——0-1背包问题和合唱队形安排问题。这两个问题都是在优化决策过程中寻找最优解的经典实例。 **一、0-1背包问题** 0-1背包问题是一个经典的约束优化...
总结来说,动态规划是通过将问题分解为更小的子问题来解决复杂问题的一种方法,它强调了问题的最优子结构和重叠子问题特性。通过理解和掌握动态规划,我们可以解决许多具有挑战性的计算问题,提高算法的效率。对于...
动态规划是一种重要的算法思想,广泛应用于计算机科学,特别是在解决最优化问题时,如 ACM(国际大学生程序设计竞赛)中的许多经典题目。动态规划的核心在于将一个复杂问题分解为多个子问题,通过解决这些子问题来...
不断地实践和总结,将帮助我们更熟练地运用动态规划,解决复杂的最优化问题。在ACM竞赛中,掌握动态规划是取得优异成绩的关键技能之一。通过不断训练,我们可以深化对动态规划的理解,提高解决问题的能力。
从给定的文件标题“算法动态规划总结(拓展篇)”和描述“算法动态规划拓展总结,内含详细解说和代码”中,我们可以提炼出一系列关于动态规划算法的知识点,这些知识点涵盖了动态规划的多种应用及其优化技术。...
文档《动态规划经典教程doc.pdf》是一份关于动态规划(Dynamic Programming,简称DP)的学习材料,主要整理了ACM(国际大学生程序设计竞赛)中经常出现的动态规划问题,并提供了解题思路和模型。动态规划是一种算法...
8.徐源盛《对一类动态规划问题的研究》 背包九讲Pack 【专辑】插头DP 【专辑】单调队列+斜率优化的DP 01背包问题 acm动态规划总结 PKU——DP专辑 背包之01 POJ 动态规划总结 背包之01背包、完全背包、多重背包详解 ...
动态规划是解决最优化问题的有效工具,其关键在于问题满足最优化原理(子问题的最优解组合成原问题的最优解)和无后效性(一旦做出某个决策,未来不会影响过去已做出的决策)。尽管动态规划可能增加空间复杂度,但在...
根据提供的文件信息,我们可以深入探讨如何使用动态规划方法来解决旅行商问题(Traveling Salesman Problem,简称TSP),并具体分析其Java实现。 ### 动态规划法解TSP 旅行商问题(TSP)是指一个旅行商需要访问一...
这是一个经典的动态规划问题,目标是在一棵由数字组成的二叉树中找到一条从叶子节点到根节点的路径,使得路径上数字之和最大。解题思路是自底向上地构建一个二维数组`number`,数组的每个元素表示从叶子节点到当前...
0-1背包问题是一个经典的优化问题,主要涉及动态规划算法的运用。在这个实验报告中,学生使用Java语言解决了一个0-1背包问题的实例。以下是关于这个问题和解决方案的详细解释。 一、问题描述: 0-1背包问题的核心是...
### 动态规划经典——背包九讲 #### 1. 01背包问题 **1.1 题目** 给定N件物品和一个容量为V的背包,每件物品都有自己的重量c[i]和价值w[i]。求解哪些物品能够放入背包内使得总价值最大。 **1.2 基本思路** 01...
0-1背包问题是一种经典的动态规划应用,它描述的是在一个容量有限的背包中,如何选择价值最大的一组物品,其中每个物品都有其重量和价值,且每个物品只能选择0个或1个。动态规划的解决方案通常采用一个二维数组,...
总结来说,动态规划是一种强大的算法工具,尤其适用于处理具有重叠子问题和最优子结构的问题。它通过存储和重用子问题的解,有效地减少了计算复杂性,广泛应用于诸如最短路径、资源分配、装载问题等领域。在应用动态...