议题:动态规划(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. 【转载】Nginx 的工作原理 和优化

    1. Nginx的模块与工作原理 Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(locati ...

  2. CodeForces 723A The New Year: Meeting Friends (水题)

    题意:给定 3 个数,求其中一个数到另外两个数之间的最短距离. 析:很明显选中间那个点了. 代码如下: #pragma comment(linker, "/STACK:1024000000, ...

  3. 阿里DNS 223.5.5.5 223.6.6.6 (转载)

    转自:http://it.oyksoft.com/post/6780/ 阿里DNS:   223.5.5.5       223.6.6.6 为何用它? 一.选择阿里DNS让你购物更爽,如果是淘宝狂人 ...

  4. P4148 简单题(KDTree)

    传送门 KDTree 修改权值当做插入节点,不平衡就暴力重构,询问的时候判断当前节点代表的矩形是否在询问的矩形的,是的话返回答案,相离返回0,否则的话判断当前点是否在矩形内,然后继续递归下去 //mi ...

  5. 原生javascript实现计时器

    成品图如意下所示: 实现加到等于5的时候停止 搭建HTML结构 minutes:<input type="text" value="0"> seco ...

  6. 题解报告:NYOJ #311完全背包(恰好装满)

    描述: 直接说题意,完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用.第i种物品的体积是c,价值是w.求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大.本题 ...

  7. WPF学习09:数据绑定之 Binding to List Data

    从WPF学习03:Element Binding我们可以实现控件属性与控件属性的绑定. 从WPF学习07:MVVM 预备知识之数据绑定 我们可以实现控件属性与自定义对象属性的绑定. 而以上两个功能在实 ...

  8. CentOS 7 下配置 firewalld(firewall-cmd)实现 NAT 转发 软路由

    如果配合 DHCP 服务或实现更多功能. ☼ NAT 转发软路由 开启 NAT 转发之后,只要本机可以上网,不论是单网卡还是多网卡,局域网内的其他机器可以将默认网关设置为已开启 NAT 转发的服务器 ...

  9. File文件存储

    文件存储的核心是Context提供了一个openFileOutput()与openFileInput()俩个方法 课程demo public class MainActivity extends Ap ...

  10. 实现通知栏Notification

    课程Demo public class MainActivity extends Activity implements OnClickListener{ NotificationManager ma ...