【NOJ1041】【DP_動態規劃】最長公共子序列
阿新 • • 發佈:2018-11-09
1041.最長公共子序列
時限:1000ms 記憶體限制:200000K 總時限:3000ms
描述
一個給定序列的子序列是在該序列中刪去若干元素後得到的序列。確切地說,若給定序列X=<x1, x2,…, xm>,則另一序列Z=<z1, z2,…, zk>是X的子序列是指存在一個嚴格遞增的下標序列 <i1, i2,…, ik>,使得對於所有j=1,2,…,k有:
Xij = Zj
如果一個序列S即是A的子序列又是B的子序列,則稱S是A、B的公共子序列。
求A、B所有公共子序列中最長的序列的長度。
輸入
輸入共兩行,每行一個由字母和數字組成的字串,代表序列A、B。A、B的長度不超過200個字元。
輸出
一個整數,表示最長各個子序列的長度。
格式:printf("%d\n");
#include <iostream> #include <string> using namespace std; string a; string b; int la,lb; int dp(int i, int j); int main() { cin>>a; cin>>b; la=a.length(); lb=b.length(); cout<<dp(la-1, lb-1)<<endl; return 0; } int dp(int i, int j) { if(i==-1||j==-1) { return 0; } else { if(a[i]==b[j]) { return dp(i-1, j-1)+1; } else { return max(dp(i-1, j),dp(i, j-1)); } } }
【後記】
1.做的第一道dp題,果然如老師所說是簡單題啊……
2.話不多說,用圖說話(愛上visio了怎麼辦_(:3 」∠ )_)
如上圖所示,i 和 j 分別指向最後一個元素
當a[ i ]==b[ j ]時,證明這個元素是最長子序列的一份子,所以return dp( i-1, j-1 )+1;
當a[ i ]!=b[ j ]時,這兩個不同的元素,每個都有可能成為最長子序列的一份子,所以return max( dp( i-1, j ), dp( i, j-1) );
上式中,max的兩個引數中,前一個是假設b[ j ]有可能成為最長子序列的一份子,而把a[ i ]去掉;後一個是假設a[ i ]有可能成為最長子序列的一份子,把b[ j ]去掉。
最後給出遞推公式叭(MathType被卸掉了在圖書館又上不了蒲公英orz,第一次嘗試LaTeX貌似還挺好用???):