• Algorithm Course Review(7.1)


      第7章,动态规划,Dynamic Programming
      又是动态规划,上一次想整理动态规划,结果还没有整理完,实际上是没有整理的动力了,整理一道题都好费时间的。
      现在又要整理,这次能整理多少了?已经开始写了,那至少有些成果吧。

      最长公共子序列问题
      书上例题,先简单分析一下,然后看与之类似的一个问题。
      给出两个长度为n和m的字符串A=a1a2..an和B=b1b2..bm,确定A和B的最长公共子序列的长度。其中,子序列的定义是形式为ai1,ai2,..aik的字符串,ij满足1<i1<i2<..<ik<n,也就是没有要求子序列是元字符串中连续的字符序列。
      为了使用动态规划技术,就需要找到最长公共子序列长度的递推公式。令L(i,j)表示A的前i个字符和B的前j个字符中最大公共子序列长度,如果i或j为0,那么L(i,j)=0,这是初始条件。当ai=bj时,最长公共子序列长度应该增加1,当ai!=bj时呢?
          i-1         i
    j-1      L(i-1,j-1)    L(i,j-1)
    j       L(i-1,j)     if ai=bj,   L(i,j)=L(i-1,j-1)+1
                 else,     L(i,j)=max(L(i,j-1),L(i-1,j))
      这就是动态规划二维矩阵的递推关系。有了这个之后,求出最大长度就是很简单的事情,但是如果要求出最长公共子序列呢?
      如果需要求出最长公共子序列的内容,需要在填写矩阵的过程这个中记录当前单元格的数字来自哪个地方,分别用左上,向左,向上的箭头表示,矩阵填写完之后,通过回溯,找出对角线上最长的箭头连线,回溯过程中箭头的优先级需要一致。
      发现下面一篇blog讲解的十分详细,给出链接http://www.cnblogs.com/zhangchaoyang/articles/2012070.html。
      另一篇也不错,http://blog.csdn.net/yysdsyl/article/details/4226630

      Google Code Jam 2012 Round 1C
      Problem C. Box Factory
      http://code.google.com/codejam/contest/1781488/dashboard#s=p2&a=2
      这是Google编程挑战赛2012年第一轮C回的第三道题,盒子工厂。题目意思是有两条生产线A和B,分别生产盒子和玩具。现在给出两条生产线上产品的数量和类型,如果两条生产线上的产品类型一致,那么把玩具放入盒子,如果不一致,你就要求选择是把盒子还是把玩具扔掉,然后继续匹配装箱。要求给出一种方案,使得最后得到的产品最多。并且只要求给出最多的这个数,不要求具体的方案。
      这道题与最长公共子序列类似,下面分析它的解法。
      f(x,y)表示两条生产线上前x个盒子和前y个玩具得到的最大的产品数,递推关系如下,
          x-1         x
    y-1      f(x-1,y-1)    f(x,y-1)
    y       f(x-1,y)     if x.type=y.type,   f(x,y)=f(x-1,y-1)+min(x.num,y.num)
                   else,          f(x,y)=max(f(x-1,y),f(x,y-1))
      代码如下,

    # BoxFactory.py
    
    import sys
    
    def ReadInt(fin):
        return int(fin.readline().rstrip("\n"))
    
    def ReadInts(fin):
        return list(int(v) for v in fin.readline().rstrip("\n").split())
    
    def BoxFactory(na,nb,A,B):
        L = [[0 for j in range(nb+1)] for i in range(na+1)]
        for i in range(1,na+1):
            for j in range(1,nb+1):
                if A[2*i-1]==B[2*j-1]:
                    L[i][j] = L[i-1][j-1] + min(A[2*i-2],B[2*j-2])
                else:
                    L[i][j] = max(L[i-1][j],L[i][j-1])
        return L[na][nb]
    
    fname = ""
    if len(sys.argv)<2:
        fname = raw_input("please input the test input:")
    else:
        fname = sys.argv[1]
    
    fin = open(fname)
    fout = open("result.txt","w")
    caseNum = ReadInt(fin)
    for case in range(caseNum):
        (na,nb) = ReadInts(fin)
        A = ReadInts(fin)
        B = ReadInts(fin)
        r = BoxFactory(na,nb,A,B)
        answer = "Case %d: %d\n" %(case+1,r)
        fout.write(answer)
    
    fin.close()
    fout.close()

      这是没有做任何修改的LCS的过程,但是测试结果中存在一些问题,页面给出的示例的第二个结果就不对,需要继续改进。

  • 相关阅读:
    Ping 笔记
    android之RadioGroup
    Android之activity中新建控件
    案例:TableLayout表格布局——迷你计算器
    android中5大布局
    Android体系结构及activity生命周期
    Android之ADB指令
    Android之activity初讲
    简单介绍Android应用特色及详解四大组件
    开发Android应用怎么更改LOGO图标
  • 原文地址:https://www.cnblogs.com/Frandy/p/algorithm_course_7_1.html
Copyright © 2020-2023  润新知