1. 程式人生 > >實驗2 動態規劃法求解最長公共子序列問題&0-1揹包問題

實驗2 動態規劃法求解最長公共子序列問題&0-1揹包問題

1 求最長公共子序列問題

1.1 概念

1.1.1 子序列

子序列: 一個序列A = a1,a2,…,an中任意刪除若干項,剩餘的序列叫做A的一個子序列。也可以認為是從序列A按原順序保留任意若干項得到的序列。

例如:對序列 1,3,5,4,2,6,8,7來說,序列3,4,8,7 是它的一個子序列。 對於一個長度為n的序列,它一共有2n 個子序列,有(2n – 1)個非空子序列。

子序列不是子集,它和原始序列的元素順序是相關的。

1.1.2 公共子序列

公共子序列 : 顧名思義,如果序列C既是序列A的子序列,同時也是序列B的子序列,則稱它為序列A和序列B的公共子序列

1.1.3 最長公共子序列

A和B的公共子序列中長度最長的(包含元素最多的)叫做A和B的公共子序列。 仍然用序列1,3,5,4,2,6,8,7和序列1,4,8,6,7,5

它們的最長公共子序列是:

1,4,8,7
1,4,6,7

最長公共子序列的長度是4 ,且最長公共子序列不唯一。 最長公共子序列問題就是求序列A= a1,a2,…,an, 和B = b1,b2,…,bm的一個最長公共子序列。

1.2 求解

在這裡插入圖片描述

用Ax表示序列A的連續前x項構成的子序列,即Ax= a1,a2,……ax, By= b1,b2,……by, 用LCS(x, y)表示它們的最長公共子序列長度,那原問題等價於求LCS(m,n)。 為了方便,用L(x, y)表示Ax和By的一個最長公共子序列。

虛擬碼如下:

for x = 0 to n do
    for y = 0 to m do
        if (x == 0 || y == 0) then 
            LCS(x, y) = 0
        else if (Ax == By) then
            LCS(x, y) = LCS(x - 1, y - 1) + 1
        else 
            LCS(x, y) = max(LCS(x – 1, y), LCS(x, y – 1))
        endif
    endfor
endfor

2 求0-1揹包問題