解題思路:
狀態:dp[i][j]-->子列c1i和子列c2j的lcs
轉移方程:dp[i][j]=dp[i-1][j-1]+1,(c1i==c2j)
=max(dp[i-1][j],dp[i][j-1]),(c1i!=c2j)
當兩子串行的最後乙個字元相同時,把兩子串行的尾部去掉(因為相同,被記錄),此時的lcs+1
當不相同時,就是找當前兩個不同的更小規模的子串行的最大值,此處《演算法導論》第三版p223有證明(雖然我也看不懂,反證法)
時間複雜度:o(nm)
ac**如下:
/*
狀態:dp[i][j]-->子列c1i和子列c2j的lcs
轉移方程:dp[i][j]=dp[i-1][j-1]+1,(c1i==c2j)
=max(dp[i-1][j],dp[i][j-1]),(c1i!=c2j)
當兩子串行的最後乙個字元相同時,把兩子串行的尾部去掉(因為相同,被記錄),此時的lcs+1
當不相同時,就是找當前兩個不同的更小規模的子串行的最大值,此處《演算法導論》第三版p223有證明(雖然我也看不懂,反證法)
時間複雜度:o(nm)
*/#include#include#include#include#includeusing namespace std;
int main()
book[m]=s;
} printf("%d\n",dp[m]);
} return 0;
}
這裡利用《演算法導論》中的方法一步步推下來,挺容易理解的(感謝)!其實就我個人能力而言,本題難點在於設計狀態的時候慣性思維會從前面往後面找,這樣那個狀態就不好設計了,而理解成兩個序列的最後乙個字元相比較,如果相同...布儒布儒布儒布儒(上面有提),《演算法競賽入門經典訓練指南》中將這個稱謂「增量法」,並且有滾動陣列的正宗做法,上面**在hdu上45ms hdu 1159 最長公共子串行
2562465 2010 06 29 17 20 23 accepted 1159 31ms 3240k 835 b c t t include include include define max size 10000 using namespace std int dp max size 1 m...
HDU1159最長公共子串行
這個題貌似是演算法導論的原題 不過本著能迴圈堅決不用遞迴的態度 我認真地寫了迴圈 關鍵其實就是乙個轉移方程 如果兩個位元組一樣,他就等於 dp a b dp a 1 b 1 1 如果不一樣就找兩邊最大的 dp a b max dp a b 1 dp a 1 b 另外在dp題裡有點找到感覺了,如果想要...
hdu 1159 公共子串行
用二維陣列f i j 記錄字串s1的前i個字元與s2的前j個字元的最大公共子串。當s1 i s2 j 時,f i j f i 1 j 1 1 否則f i j max f i 1 j f i j 1 include include define max a,b a b?a b define n 100...