lcs也是經典dp問題啦~o(nm)的時間複雜度,滾動陣列優化空間複雜度
a.common subsequence poj - 1458
lcs的模板題~
tips:讀字串的時候是從下標為0開始的,不是1哦
#include
#include
#include
using
namespace std;
char str1[
1005
],str2[
1005];
int dp[
1005][
1005];
intmain()
}printf
("%d\n"
,dp[len1]
[len2]);
}return0;
}
b.palindrome poj - 1159 / 洛谷p1435 回文字串
tips:將原字串逆序得到另乙個字串,求它們的最長公共子串行,這樣就能求得它的可以構成回文的最長字元數.(正序與倒序「公共」的部分就是回文的部分)
注意poj 1159開5005*5005的int會爆記憶體~要開成short!
另外逆序字串可以不用新開乙個陣列,也可以直接在原陣列上從後往前迴圈。(注意algorithm裡的reverse沒有返回值哦)
#include
#include
#include
using
namespace std;
int len;
short dp[
5005][
5005];
string s1,s2;
intmain()
printf
("%d"
,len - dp[len]
[len]);
return0;
}
其實空間可以再優化~就想01揹包一樣,dp陣列只會用到i - 1行的資料,0-(i-2)行的資料是用不上的。我們可以用乙個滾動陣列來求解問題:
空間優化後的**:
//lcs空間優化
#include
#include
#include
using
namespace std;
int len,dp[2]
[5005
],cur,pre;
string s1,s2;
intmain()
printf
("%d"
,len - dp[pre]
[len]);
//注意這裡必須是pre!因為做完之後會把pre和cur交換
return0;
}
c.compromise poj - 2250
lcs列印序列~ 只是把單詞當做整體,實質就是lcs. 可以採用dfs來輸出,注意只有當
ans == dp[x - 1][y - 1] + 1 && ans == dp[x - 1][y] + 1 && ans == dp[x][y - 1] + 1才算確定的找到~
p.s.本題多組輸入哦.
#include
#include
#include
using
namespace std;
int dp[
105]
[105
],len1,len2,cnt;
string str1[
105]
,str2[
105]
,s,road[
105]
;void
dfs(
int ans,
int x,
int y)
intmain()
cin >> s;
while
(s !=
"#")
memset
(dp,0,
sizeof
(dp));
for(
int i =
1; i <= len1;
++i)
}dfs
(dp[len1]
[len2]
,len1,len2)
; cout << road[1]
;for
(int i =
2; i <= dp[len1]
[len2]
;++i)
cout <<
" "<< road[i]
;putchar
('\n');
}return0;
}
動態規劃(最長相同子串行,遞增)
最長相同子串行 include string.h int main int argc,char argv printf d n f len1 len2 return 0 求最長遞增子串行 也可以先排序然後與原來的一起求最長相同子串行 include stdio.h include string.h ...
最長公共子串LCS
找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。其實這又是乙個序貫決策問題,可以用動態規劃來求解。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧 bab 和 caba 當然我們現在一眼就可以看出來最長公共子串是 ba 或 ab b a b c 0 0 0 a ...
最長公共子串(LCS)
找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。其實這又是乙個序貫決策問題,可以用動態規劃來求解。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧 bab 和 caba 當然我們現在一眼就可以看出來最長公共子串是 ba 或 ab b a b c 0 0 0 a ...