动态规划P1S.pptVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
动态规划P1S

动态规划 Dynamic Programming Part 1 Second Day Alphard 2008.8 内容提要 一、最长公共子序列 二、最长上升子序列 最长公共子序列 Longest Common Subsequence(LCS) 给两个序列,找出他们共有的最长子序列。 C A B N M O P L S A X B S A O M L A X N A M L A X 最长公共子序列 分析:考虑两个序列X、Y,X[0]到X[i]构成的序列(以后简记为序列X[i])以及Y[0]到Y[j]构成的序列 如果X[i] != Y[j],序列X[i]与序列Y[j]的LCS长度为序列X[i-1]与序列Y[j]或序列X[i]与序列Y[j-1]的LCS长度 如果X[i] == Y[j],则序列X[i]与序列Y[j]的LCS长度为X[i-1]与序列Y[j-1]的LCS长度+1 (以上的证明参考《算法导论》) 最长公共子序列 状态表示:Dp[i][j]表示序列X[i]与序列Y[j]的LCS长度 状态转移: 这样,求LCS长度就解决了。 if X[i] = Y[j] then Dp[i][j] = Dp[i-1][j-1] + 1 else Dp[i][j] = Max{Dp[i][j-1],Dp[i-1][j]} 最长公共子序列 那么如何求解LCS呢? LCS可能有很多个,一般只要求出其中一个即可 观察之前的状态转移方程式,我们可以记录决策的位置,最后逆推回去即可 自底向上递推 变形. 回文词 给一个字符串a, 保持原字符的顺序不变, 至少要加几个字符才能变成回文词? 例: abfcbfa ? afbcfcbfa 分析 红、绿色表示原字符, 白色为新增字符 显然, s和s’在任何一个位置不可能都是白色(不需要加那个字符!) 应该让红色字符尽量多! 相当于求s和逆序串s’的LCS, 让LCS中的对应字符(红色)对齐, 中间的每个绿色字符都增加一个字符和它相等 最长上升子序列 Longest Increasing Subsequence 给一个序列,求它的一个递增子序列,使它的元素个数尽量多。 例如序列1,6,2,5,4,7的最长上升子序列是1,2,5,7(还有其他的,这里略去) 最长上升子序列 定义d[i]是从第1个元素到第i个元素为止的最长子序列长度, 则状态转移方程为 d[i] = Max{d[k] + 1} (1 = k i a[k] a[i]) 直接使用这个方程得到的是O(n2)算法 下面把它优化到O(nlogn) 状态的组织 d值相同的a值只需要保留最小的, 因此用数组g[i]表示d值为i的数的a最小值, 显然 g[1]=g[2]=…=g[k] 计算d[i]: 需要在g中找到大于等于a[i]的第一个数j, 则d[i]=j 更新g: 由于g[j]a[i], 需要更新g[j]=a[i] 例子 观察如下过程 a 1 3 g 4 7 d 5 4 3 2 3 2 4 3 2 1 2 3 7 5 3 1 2 4 代码 使用STL的lower_bound可以直接求出比a[i]大的第一个数, 用二分查找实现, 每次转移时间O(logn), 总时间O(nlogn) fill(g,?g?+?n,?infinity); for(int?i?=?0;?i??n;?i++){ int?j?=?lower_bound(g,?g?+?n,?a[i])?-?g; ??d[i]?=?j?+?1; ??g[j]?=?a[i]; } 变形1: 航线问题 有两行点, 每行n个. 第一行点和第二行点是一一对应的, 有线连接, 如下图所示 选择尽量多的线, 两两不交叉 分析 设与第1行第i个点对应的是第2行第f[i]个点 假设ij, 两条线(i, f[i])和(j, f[j])的充要条件是f[i]f[j], 因此问题变成了 求f的最长上升子序列 时间复杂度为O(nlogn) 变形2: 两排列的LCS 给1~n的两个排列p1, p2 求p1和p2的最长公共子序列 例: 1 5 3 2 4 ? 5 3 4 2 1 分析 算法一: 直接套用LCS算法, 时间O(n2) 算法二: 注意到把两个排列做相同的置换, LCS不变, 可以先把p1排列为1,2,3…,n 1 5 3 2 4 ? 1 2 3 4 5 即映射5?2, 2?4, 4?5, p2作同样置换 5 3 4 2 1 ? 2 3 5 4 1 与1,2,3..n的LCS显然是最长上升子序列, 时间降为O(nlogn) 练习 NKOJ 1635 Subsequence 1278 区间相

文档评论(0)

xcs88858 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

版权声明书
用户编号:8130065136000003

1亿VIP精品文档

相关文档