之前在程式設計課上對該知識點進行過解析,不過今天又重溫一遍,感覺邏輯又相對清晰了一些,所以寫一下想法。
這四個問題是非常經典的問題,我們可能都會做,但每次做之前要思考一陣子才能把邏輯理清,這說明對於一些原則性的東西把握不清,而我們爭取做到把每個問題都能理成一條線,使其不處於混沌狀態。比如,之前考試最後一道題目應當是揹包問題,經典揹包問題我們應當都會,但記住的只是**該怎麼寫,一但問題變形,需要再深度思考的時候,就會感覺含糊不清,變數儲存弄混,思路扯不出來。
我們首先從公共與回文上面進行分析,公共的意思便是給出了兩串,而回文則是僅給出了乙個串。毫無疑問,dp問題都是小問題更新大問題,但小問題的定義是本身是相對的,乙個問題能夠直接更新或者是間接更新另乙個問題,則其相對於另乙個問題便可稱之為小問題,形象的來講,我們可以將看作問題與其直接子問題之間利用箭頭相連,這樣的話我們dp的整個過程便是在尋找一條拓撲路徑,最終走向最大問題。
因此我們解決問題的關鍵在於定一下狀態,規定大問題是如何由以及由哪些小問題更新來的。對於公共以及回文來講,可以明顯的感覺到狀態是二維的。而對於公共來講,很明顯問題的子問題的兩個維度都要小於等於該問題的兩個維度。所以簡單的二重迴圈便可以了,其中每乙個維度都附著在乙個串上。在這個意義上,其便是乙個座標型的dp。
對於回文來講,也很顯然,其是乙個回文區間的擴充,其擴充方向是雙向的,因此,我們不能夠用通俗意義下的二重遞增迴圈,我們要進行改變或賦予其新的意義。在這裡,其是一種區間dp的形式。區間dp顯然就是要利用小區間去更新大區間。第一種方法我們可以用第一維表示區間的長度,第二維表示從那個下標開始。第二種方法我們可以採用第一維遞減第二維遞增的方式進行迴圈,意義為從下標i到下標j之間的回文序列的長度。關於兩種方式,其原則是一樣的,乙個問題直接由三個子問題決定,所以我們的迴圈方式保證這三個子問題能夠提前解決就行了。
另外講一下關於子串行與子串的區別,子串行的要求相對較鬆一點,乙個問題的值只會大於等於其子問題的值,而子串則其只有乙個子問題,如果滿足條件,其值要大於子問題,否則,其值為0。
最長公共子串行 最長公共子串
1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...
最長公共子串行 最長公共子串
1.區別 找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。而最長公共子串行則並不要求連續。2 最長公共子串 其實這是乙個序貫決策問題,可以用動態規劃來求解。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧 bab 和 caba 當然我們現在一眼就可以看出來最長公...
最長公共子串 最長公共子串行
子串要求連續 子串行不要求連續 之前的做法是dp求子序列 include include include using namespace std const int inf 0x3f3f3f3f const int mod 1000000007 string s1,s2 int dp 1010 10...