最长公共子串(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

ContractedBlock.gif ExpandedBlockStart.gif 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类型水过。。。。。。

ContractedBlock.gif ExpandedBlockStart.gif 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 }



转载于:https://www.cnblogs.com/dongjinwei/archive/2011/10/25/2224122.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值