• 动态规划应用(1)


      废话不说,直接入主题。这次讨论的是动态规划问题。动态规划可通过找重叠的子问题,以及解决子问题的方法进行问题化简最终达到解决的目的。以例子进行说明:寻找最长公共子序列;寻找非降序最长子序列。

      1.寻找最长公共子序列

    题目:两个序列A、B,长度不定,寻找其最长公共子序列,要求顺序一致。

    印象:其中一个做标准A,B则用于与标准进行比对。但是B的元素如果在A中找到了,要如何操作,没有找到又要怎样,顺序问题怎么解决呢。

    分析:a.解题的思路就是将问题由大化小,当然还要知道小问题如何解决。

       b.由大化小:都是两个序列求解最长公共序列,这是每个问题的相同部分。可通过将序列变短以达到由大化小的目的。

        c.小问题解决方法:最简单的小问题是:两个只有一个元素的序列求解,相等即是公共解。

        d.分别具有两个元素的序列A,B:如果A序列第一个元素a1与B中第一个元素b1相等,则可算为公共序列。在此基础上,将a2与b2进行比对即可;

      如果a1!= b1,则公共解可能产生于a1=b2 or a2=b2,即是A序列(a1,a2)与b2求解公共最长序列;公共解也可能产生于b1=a2 or b2=a2,即是B序列与a2求解最长公共序列,至于是那种可能性,当然是两者之间公共序列最长的那个。

    题解(未写成程序):

        A:a1,a2,a3,a4,……,an

        B:b1.b2,b3,b4,……,bm

        由分析可知,当a1=b1时,即化成序列A2(a2--an)与B2(b2--bm)求解最长公共序列;当a1!=b1时,即是在A2与B1,A1与B2两种当中选择具有最长公共序列的即是。

        计算时,需要先将An与Bm的公共解求出(标记为c(n,m),c为公共序列中含有元素的个数),再将序列An-1与Bm公共解求出(c(n-1,m)),序列An与Bm-1公共解求出(c(n,m-1));An-1与Bn-1的公共解(c(n-1,m-1)即可通过c(n,m),c(n-1,m),c(n,m-1)求出。规则是:当an-1=bm-1时,将从c(n,m)+1即是当前最长公共序列所含元素个数,an-1即是公共序列的元素之一。当an-1!=bm-1时,即是查看c(n-1,m)和c(n,m-1)中哪个大,就选哪个作为c(n-1,m-1)的值,它所含有的公共元素也是由c(n-1,m)或是 c(n,m-1)决定(看选的是哪个了)。

    2.寻找最长非降序子序列

    题目:多个元素组成的一个无序的序列,求其最长、非降序、子序列。

    印象:非降序,子序列都好说,如何达到最长,是个问题。

          一个元素的序列,它的最长非降序子序列(后简称解)就是这个元素;两个元素组成的序列,就需要查看第二个元素是否大于等于第一个元素,决定结果;三个元素组成的序列,需要查看是否大于第一个元素,是否大于第二个元素,还得看看两个元素时的结果来综合考虑它的解是什么。

          这样做很麻烦,也很乱。这样做之所以麻烦,是因为在每增加一个元素的时候,我都想得出当前那个元素在最后的解之中,哪个元素不在。其实可以换一种想法,每增加一个元素,就认为它在解中,也就是确定了在当前情况下结尾的那个数(新增加的那个元素)。那么为了满足非降序条件,需要最后一个元素大于等于它前面的元素,也就是他前面的都小于等于最后一个元素。

    分析:依然是由大化小。假定以当前序列的每一个元素为最后一个元素的解都已经存在,那么每增加一个元素我们在它前面找到比其小于等于的元素,找到比较哪一个对应的解比较长,就把最好的放在新增加的这个元素的前面,即是求出了以新增元素为结尾的解。

    题解(未写成程序):

    假定序列A:1,5,6,1,2,3……

           以哪个元素为结尾                         比其小的元素(对应的解)                               对应的解

                1                                                      null                                                                    1

                       5                                                      1(1)                                                                    1,5

                       6                                                      1(1),5(1,5)                                                       1,5,6

                       1                                                      1(1)                                                                   1,1

                       2                                                      1(1),1(1,1)                                                       1,1,2

                       3                                                      1(1),1(1,1),2(1,1,2)                                       1,1,2,3

           ……                                                 ………………                                               ………

    这样推算下去,直到真正的最后一个元素,结果即可得出。

     

  • 相关阅读:
    JavaScript递归函数解“汉诺塔”
    《JavaScript DOM编程艺术》学习笔记(三)
    《JavaScript DOM编程艺术》学习笔记(二)
    《JavaScript DOM编程艺术》学习笔记(一)
    《手把手教你实现电商网站开发》课程学习总结
    学校水卡、本地公交卡破解记
    第一篇博客
    mysql5.7.5以上版本使用distinct和order by 报错备忘录
    group_concat长度限制踩坑备忘录
    ArrayList、LinkedList、Vector的区别
  • 原文地址:https://www.cnblogs.com/wenhuozhujiangcha/p/dynamic_programming.html
Copyright © 2020-2023  润新知