最长公共子串(LCS:longest common subsequence)

最长公共子串是动态规划的一种经典应用。设X = {x1,x2,...xm},Y = {y1,y2,..,yn}为两个序列,并设Z = {z1,z2,...,zk}为X和Y的任意一个LCS,那么有3种情况:

  1. 如果xm = yn,那么zk=xm=yn 而且Zk-1是Xm-1和Yn-1的一个LCS。
  2. 如果xm != yn,那么zk!=xm,蕴含Z是Xm-1和Y的一个LCS。
  3. 如果xm != yn,那么zk!=yn,蕴含Z是X和Yn-1的一个LCS。

POJ1458 http://poj.org/problem?id=1458

题意:标题就叫做common subsequence

View Code
 1 #include <iostream>
2 #include <string>
3 #define SIZE 1001
4
5 using namespace std;
6
7 int dp[SIZE][SIZE];
8
9 int main()
10 {
11 string str1,str2;
12 while (cin>>str1>>str2)
13 {
14 int len1 = str1.size();
15 int len2 = str2.size();
16
17 if(str1[0] != str2[0]) //init
18 dp[1][1] = 0;
19 else
20 dp[1][1] = 1;
21
22 for (int i=1;i<=len1;i++) //LCS(longest common subsequence)
23 {
24 for(int j=1;j<=len2;j++)
25 {
26 if (i!=1||j!=1)
27 {
28 if(str1[i-1] == str2[j-1])
29 dp[i][j] = dp[i-1][j-1]+1;
30 else
31 dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
32 }
33 }
34 }
35
36 cout<<dp[len1][len2]<<endl;//output
37
38 }
39
40 return 1;
41 }

 

POJ1159 http://poj.org/problem?id=1159

题意:介绍一种定义palindrome(顺着和逆着读都相同的字符串就叫做palindrome),给你一个字符串,以最少的字符加入其中使其变成palindrome。求最少字符个数

分析:其实是LCS的变形,我们可以求其字符串和其逆序的LCS,则最少字符个数就等于len-LCS。要注意要用滚动数组,不然会超过内存限制,不过可以用short类型水过。。。。。。

View Code
 1 #include <iostream>
2 #include <string>
3 #define SIZE 5001
4
5 using namespace std;
6
7 short dp[SIZE][SIZE];
8 char str1[SIZE],str2[SIZE];
9
10 int main()
11 {
12 int len;
13 cin>>len;
14 for (int i=0;i<len;i++)
15 {
16 cin>>str1[i];
17 str2[len-i-1] = str1[i];
18 }
19
20 if(str1[0] != str2[0]) //init
21 dp[1][1] = 0;
22 else
23 dp[1][1] = 1;
24
25 for (int i=1;i<=len;i++) //LCS(longest common subsequence)
26 {
27 for(int j=1;j<=len;j++)
28 {
29 if (i!=1||j!=1)
30 {
31 if(str1[i-1] == str2[j-1])
32 dp[i][j] = dp[i-1][j-1]+1;
33 else
34 dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
35 }
36 }
37 }
38
39 cout<<len-dp[len][len];//output
40 return 1;
41 }



posted @ 2011-10-25 16:40  南风又起  阅读(245)  评论(0编辑  收藏  举报