动态规划 短命女 2022-05-17 09:45 341阅读 0赞 等我有时间了,一定要把《算法导论》啃完,这本书的印刷质量实在太好了,就是烧脑子,滑稽。 适合应用动态规划求解的最优化问题应该具备两个要素: **最优子结构**:一个问题的最优解包含其子问题的最优解; **子问题重叠**:子问题的空间足够小,问题的递归算法会反复求解相同的子问题,而不是一直生成新的子问题。 常见的可以用动态规划解决的问题有: ① 0-1背包问题 ② 最长公共子序列 ③ 最短路径 ④ 最优二叉搜索树 ### ① 0-1背包问题 ### 问题描述:给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 wi,其价值为 vi 。问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大? 思路分析:动态规划的出发点就是要把问题分解为子问题,并找到子问题之间的递推关系式。 对于背包问题,一个物品要么放进包里要么不放进包里,就是说对于第i 个物品,能不能放进包里。第i 个物品能放进去的时候,是放进去收益大还是把空间流出来收益大。根据这个分割,可以找到这个背包对前i 种物品的解与对前i-1 种物品的解之间的关系。 ![70][] Java实现如下 public static int DP01(int[] weight, int[] value, int capcity) { int[][] best = new int[value.length+1][capcity+1]; for(int i=0;i<value.length+1;i++) best[i][0]=0; for(int i=0;i<capcity+1;i++) best[0][i]=0; for(int i=1;i<value.length+1;i++){ for(int j=1;j<capcity+1;j++){ if(weight[i-1]>j){ best[i][j] = best[i-1][j]; }else{ best[i][j] = Math.max(value[i-1]+best[i-1][j-weight[i-1]], best[i-1][j]); } } } return best[value.length][capcity]; } ### ② 最长公共子序列(LCS) ### 问题描述: 设两个序列X=\{x1,x2,...,xm\},Y=\{y1,y2,...,yn\},求XY的最长公共子序列。 思路分析:这个问题的分解的入手点是看xm是不是等于yn,而问题规模大小来自两个序列的长度。 若xm=yn,那么Xm 与Yn 的LCS 为Xm-1 与Yn-1 的LCS + xm,长度为后者的长度+1; 若xm!=yn,那么 Xm 与Yn 的LCS 为Xm-1 与Yn 的LCS 或者Xm 与Yn-1 的LCS,从这两者中选出较长的一个,我们定义c\[i,j\] 为Xi 和Yj 的LCS 长度,即Xm 的前 i 项和Yn 的前 j 项的LCS长度,得到一个递推的关系式。 ![2012111100085930.png][] 分析的时候自顶向下,发现求解过程是递归的,但用递归求解的话因为子问题的重叠,会导致重复计算,增加时间复杂度(因为i,j 的取值,会导致重复计算c\[i-1,j-1\]、c\[i,j-1\]、c\[i-1,j\]),所以在求解的时候采用自底向上循环求解,也就是动态规划。 Java实现如下 public static int LCS(char[] x, char[] y) { int[][] lcs = new int[x.length+1][y.length+1]; int[][] direction = new int[x.length+1][y.length+1];//1-左上角,2-上面,3左边 lcs[0][0] = 0; lcs[0][1] = 0; lcs[1][0] = 0; for(int i=1;i<=x.length;i++){ for(int j=1;j<=y.length;j++){ if(x[i-1]==y[j-1]){ lcs[i][j] = lcs[i-1][j-1]+1; direction[i][j] = 1; }else if(lcs[i-1][j]> lcs[i][j-1]){ lcs[i][j] = lcs[i-1][j]; direction[i][j] = 2; }else{ lcs[i][j] = lcs[i][j-1]; direction[i][j] = 3; } } } StringBuilder result = new StringBuilder(); for(int i=x.length,j=y.length;i>0&&j>0;){//沿着路径往回找 switch(direction[i][j]){ case 1: result.append(x[i-1]);//相同的字符 i--; j--; break; case 2: i--;break; case 3: j--;break; default: break; } } System.out.println(result.reverse()); return lcs[x.length][y.length]; } 可以用,某些刷题网站的测试用例验证一下,我还没找到。 [70]: /images/20220517/a29945b943c54567b2e62b400d2a5f35.png [2012111100085930.png]: /images/20220517/c8edf581170e49dbb518f194b53680c6.png
相关 动态规划 一:概念: 和分冶法相似,不同之处在于前者是把问题划分为互不相交的子问题,而动态规划会出现子问题重叠的情况。通常用来求解最优化问题。。 基本步骤: ①:刻画一个最优 我就是我/ 2022年12月01日 11:51/ 0 赞/ 42 阅读
相关 动态规划 -------------------- 动态规划的设计思想 动态规划(DP)\[1\]通过分解成子问题解决了给定复杂的问题,并存储子问题的结果,以避免再次计算相同的结 柔情只为你懂/ 2022年09月25日 11:15/ 0 赞/ 266 阅读
相关 动态规划 作者:Hawstein 出处: [http://hawstein.com/posts/dp-novice-to-advanced.html][http_hawstein.c 淡淡的烟草味﹌/ 2022年09月24日 12:17/ 0 赞/ 219 阅读
相关 动态规划 1. 首先,动态规划不是一个特定的算法,它代表的是一种思想,一种手段 2. 动态规划方法往往用于求解“最优化问题”,能用动态规划求解的问题的前提是问题具有“最优子结构性质” 刺骨的言语ヽ痛彻心扉/ 2022年07月29日 11:46/ 0 赞/ 113 阅读
相关 动态规划 首先是概念:动态规划就是将原问题划分为简单的几个小问题(有点类似与分治法?但是分治法中的各个小问题是相互独立的,彼此之间不会产生影响,但是动态规划中所得的值和前面相关,当前的解 青旅半醒/ 2022年07月12日 05:01/ 0 赞/ 333 阅读
相关 动态规划 > 给定两个字符串A和B,返回两个字符串的最长公共子序列的长度。例如,A=”1A2C3D4B56”,B=”B1D23CA45B6A”,”123456”或者”12C4B6”都是最 以你之姓@/ 2022年06月07日 00:41/ 0 赞/ 332 阅读
相关 动态规划 基本思想: 动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。 区别: 与 ゞ 浴缸里的玫瑰/ 2022年05月25日 09:44/ 0 赞/ 459 阅读
相关 动态规划 等我有时间了,一定要把《算法导论》啃完,这本书的印刷质量实在太好了,就是烧脑子,滑稽。 适合应用动态规划求解的最优化问题应该具备两个要素: 最优子结构:一个问题的最优解包含 短命女/ 2022年05月17日 09:45/ 0 赞/ 342 阅读
相关 动态规划 1.题目:最长递增子序列(Longest Increasing Subsequence) 问题描述: > 给定长度为N的数组A,计算A的最长单调递增的子序列(不一定连续) 妖狐艹你老母/ 2022年05月11日 04:56/ 0 赞/ 297 阅读
相关 动态规划 算法题中动态规划是真的难,写一篇总结,彻底解决动态规划。参考:[https://blog.csdn.net/u013309870/article/details/7519359 左手的ㄟ右手/ 2021年11月19日 14:14/ 0 赞/ 520 阅读
还没有评论,来说两句吧...