议题:动态规划(Dynamic Programming)

分析:

  • DP主要用于解决包含重叠子问题(Overlapping Subproblems)的最优化问题,其基本策略是将原问题分解为相似的子问题,通过求解并保存最简单子问题的解,然后逐步合并成为原问题的解,由于需 要查询子问题的解,所以需要一个表格记录子问题的解;DP仅适用于最优子结构问题(Optimal Substructure),也就是局部最优解相当于(或者近似于)全局最优解;

  • 对于原问题而言,当递归地自顶向下对问题进行求解时,每次产生的子问题可能与之前差生的子问题重复(如Fibonacci数列的求解);DP通过自底向上 求解子问题的解并将其保存在一个表格中,当再次遇到相同子问题时就直接通过查表得到其解(分治算法的子问题则是完全独立子空间);使用DP之前需要判定当 前问题是否具有下述三个特性:

    最优子结构:无论之前的状态和决策如何,当前的局部最优解是构成全局最优解的必要条件;

    无后效性:对于某个给定的阶段状态而言,在此之前的所有决策和状态都无法直接影响未来的决策,而只能通过当前的决策和状态影响;

    空间需求度:DP实际上是一种空间换时间的策略,在求解的过程中需要不断存储子问题的解并提供合理的查询方式;

  • DP的四个步骤

    划分阶段:注意划分之后的阶段必须是有序或者可排序的;

    确定状态和状态变量:将划分后的子问题使用不同状态表示,并满足无后效性;

    确定决策并写出状态转移方程:根据相邻两个阶段的状态关系得出转移方程;

    寻找边界条件:给出的转移方程是一个递归式,需要最终确定一个终止条件;

    最长公共子序列的DP解法

  • LCS问题与LIS(Largest Incremental Sub-sequence)问题类似,将原字符串A进行排序之后得到B,则A的LIS就是A和B的LCS。另外也可以直接使用DP;

  • 解法1:Largest Common Sub-string,如果将需求理解为公共子串的字符必须相连,则解法如下:将字符串A的每一个字符依次匹配B的每一个位置,时间复杂度O(MN),M 和N分别为A和B的长度,同样也可以使用DP填表的方式求解。KMP算法也可以求解,时间复杂度为O(M+N);

  • 解法2:Largest Common Sub-Sequence,如果将需求理解为公共子串的字符可以分离,则为经典的LCS问题(也可以理解为求两个集合的顺序交集),则解法如下:动态规划 (DP),动态规划一般应用于具有最优子结构的问题,也就是局部最优解可以决定全局最优解;动态规划的关键点在问题的拆分和状态关系的转移;

  • 给定first[1,m]和second[1,n],求LCS(first[1,m],second[1,n]),

    如果first和
    second的最后一个字符相同,则有first[m]=second[n]=result[k],这样问题化解为给定first[1,m-1]和
    second[1,n-1],求LCS(first[1,m-1],second[1,n-1]),原问题转化为
    LCS(first[1,m],second[1,n])= LCS(first[1,m-1],second[1,n-1]) +1

    如果first和second的最后一个字符不相同,则问题化解为result[1,k]= max{LCS(first[1,m-1],second[1,n]), LCS(first[1,m],second[1,n-1])

样例:

 /**
* 利用动态规划,使用簿记matrix的方法记录小子问题,然后重复利用
* 小子问题解决合成问题,最终解决整个问题。
* 在first和second组成的二维表中,一共有三种状态转移方式:
* 如果first[m]=second[n],则跳到first[m-1]和second[n-1]
* 如果first[m]!=second[n],则跳到first[m-1]和second[n],
* first[m]和second[n-1]的LCS中较大的一个
* 需要设定初始状态为0
* */
void lcs2(char *first, int lfirst, char *second, int lsecond) {
int *dir=new int[lfirst*lsecond];
int *dis=new int[lfirst*lsecond];
/**
* 保留first和second的第一个字符,将其dis设置为0,便于实现簿记
* dir矩阵中:0表示up-left移动;1表示left移动;2表示up移动
* */
for(int i=;i<lfirst;i++)
dis[i]=;
for(int i=;i<lsecond;i++)
dis[i*lfirst]=; for(int j=;j<lsecond;j++) {
for(int i=;i<lfirst;i++) {
if(first[i]==second[j]) {
/**
* 如果当前字符相等,则说明[i,j]长度的LCS为
* [i-1,j-1]长度的LCS 加上1;
* up-left移动
* */
dis[i+j*lfirst]=
dis[(i-)+(j-)*lfirst]+;
dir[i+j*lfirst]=;
} else if(dis[i+(j-)*lfirst] >
dis[(i-)+j*lfirst]) {
/**
* 如果当前字符不等,并且[i,j-1]长度的LCS大于
* [i-1,j]长度的LCS,则当前[i,j]长度的LCS等于
* [i,j-1]产度的LCS
* up移动
* */
dis[i+j*lfirst]=
dis[i+(j-)*lfirst];
dir[i+j*lfirst]=;
} else {
/**
* 如果当前字符不等,并且[i-1,j]长度的LCS大于
* [i,j-1]长度的LCS,则当前[i,j]长度的LCS等于
* [i-1,j]产度的LCS
* left移动
* */
dis[i+j*lfirst]=
dis[(i-)+j*lfirst];
dir[i+j*lfirst]=;
}
}
} showLCS(first, dir, lfirst-, lsecond-, lfirst); delete [] dir;
delete [] dis;
}

参考连接:
http://blog.csdn.net/v_july_v/article/details/6695482
http://en.wikipedia.org/wiki/Dynamic_programming
http://blog.csdn.net/sharpdew/article/details/763180

笔试算法题(44):简介 - 动态规划(Dynamic Programming)的更多相关文章

  1. 动态规划(Dynamic Programming)算法与LC实例的理解

    动态规划(Dynamic Programming)算法与LC实例的理解 希望通过写下来自己学习历程的方式帮助自己加深对知识的理解,也帮助其他人更好地学习,少走弯路.也欢迎大家来给我的Github的Le ...

  2. 6专题总结-动态规划dynamic programming

    专题6--动态规划 1.动态规划基础知识 什么情况下可能是动态规划?满足下面三个条件之一:1. Maximum/Minimum -- 最大最小,最长,最短:写程序一般有max/min.2. Yes/N ...

  3. 动态规划Dynamic Programming

    动态规划Dynamic Programming code教你做人:DP其实不算是一种算法,而是一种思想/思路,分阶段决策的思路 理解动态规划: 递归与动态规划的联系与区别 -> 记忆化搜索 -& ...

  4. [算法]动态规划(Dynamic programming)

    转载请注明原创:http://www.cnblogs.com/StartoverX/p/4603173.html Dynamic Programming的Programming指的不是程序而是一种表格 ...

  5. Python算法之动态规划(Dynamic Programming)解析:二维矩阵中的醉汉(魔改版leetcode出界的路径数)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_168 现在很多互联网企业学聪明了,知道应聘者有目的性的刷Leetcode原题,用来应付算法题面试,所以开始对这些题进行" ...

  6. 动态规划 Dynamic Programming

    March 26, 2013 作者:Hawstein 出处:http://hawstein.com/posts/dp-novice-to-advanced.html 声明:本文采用以下协议进行授权: ...

  7. 动态规划 Dynamic Programming 学习笔记

    文章以 CC-BY-SA 方式共享,此说明高于本站内其他说明. 本文尚未完工,但内容足够丰富,故提前发布. 内容包含大量 \(\LaTeX\) 公式,渲染可能需要一些时间,请耐心等待渲染(约 5s). ...

  8. 动态规划-Dynamic Programming(DP)

    动态规划 动态规划方法心得 ​ 动态规划是一般的面试.笔试中的高频算法题,熟练掌握必要的.动态规划的中心思想是在解决当前问题时,可以由之前已经计算所得的结果并结合现在的限制条件递推出结果.由于此前的计 ...

  9. 动态规划系列(零)—— 动态规划(Dynamic Programming)总结

    动态规划三要素:重叠⼦问题.最优⼦结构.状态转移⽅程. 动态规划的三个需要明确的点就是「状态」「选择」和「base case」,对应着回溯算法中走过的「路径」,当前的「选择列表」和「结束条件」. 某种 ...

随机推荐

  1. Ubuntu 环境变量及 ADB 配置 (转载)

    转自:http://blog.csdn.net/ithomer/article/details/7307449 同Windows一样,Ubuntu Linux系统包含两类环境变量:系统环境变量和用户环 ...

  2. P4323 [JSOI2016]独特的树叶(树哈希)

    传送门 树哈希?->这里 反正大概就是乱搞--的吧-- //minamoto #include<bits/stdc++.h> #define R register #define l ...

  3. Visual Studio 2015 个版本下载

    Visual Studio 2015是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具.代码管控工具.集成开发环境(IDE)等等.所写的目标代码适用于微软支持的所有 ...

  4. 动态规划基础复习 By cellur925

    结束帝都的qbxt dp图论精讲班后,感觉自己依然很水,接下来的一周,不妨来复习一下讲课内容:) 动态规划是lyd讲的,上次在泉城讲数据结构,然鹅体验较差,这次虽说好了些,但还是比想象中的效果不好(还 ...

  5. ROS学习笔记九:ROS工具

    ROS有各种工具可以帮助用户使用ROS.应该指出,这些GUI工具是对输入型命令工具的补充.如果包括ROS用户个人发布的工具,那么ROS工具的数量很庞大.其中,本文讨论的工具是对于ROS编程非常有用的辅 ...

  6. zoj 3649 lca与倍增dp

    参考:http://www.xuebuyuan.com/609502.html 先说题意: 给出一幅图,求最大生成树,并在这棵树上进行查询操作:给出两个结点编号x和y,求从x到y的路径上,由每个结点的 ...

  7. 题解报告:poj 1195 Mobile phones(二维BIT裸题)

    Description Suppose that the fourth generation mobile phone base stations in the Tampere area operat ...

  8. [转]如何在 TFS 中使用 Git

    本文转自 http://www.cnblogs.com/stg609/p/3651688.html 对 Charley Blog 的代码进行版本控制的想法由来已久,在代码建立之初其实已经使用过 TFS ...

  9. Partial(部分方法,局部方法),virtual(虚方法),abstract(抽象方法)

    Partial 部分方法顾明思议是方法的一部分,不完整的,在ide编译时候,会将所有部分方法加载到一起统一编译,如果分部方法没有被实现,编译器就不会.对他们进行编译. 局部类型的限制 (1) 局部类型 ...

  10. Dev之GridControl详解

    Dev控件中的表格控件GridControl控件非常强大.不过,一些细枝末节的地方有时候用起来不好找挺讨厌的.使用过程中,多半借助Demo和英文帮助文档.网上具体的使用方法也多半零碎.偶遇一个简单而且 ...