hdu 1159 Common Subsequence(dp 最长公共子序列问题LCS)



最长公共子序列问题(LCS,Longerst Common Subsequence)

s1s2……si+1和t1t2……tj+1的公共子序列可能是:

  ①当si+1=tj+1时,在s1s2……si+1和t1t2……tj+1的公共子序列末尾追加一个。

  ②s1s2……si+1和t1t2……tj的公共子序列

  ③s1s2……si和t1t2……tj+1的公共子序列

所以易得到递推关系dp[i+1][j+1]=   max{ dp[i][j]+1 , dp[i][j+1] , dp[i+1][j]) }   (当si+1=tj+1时)

                  max{ dp[i][j+1] , dp[i+1][j]) }     (其他)

最后得到的dp[n][m]就是LCS的长度。

同时稍微思考一下,就可以发现当si+1=tj+1时,dp[i+1][j+1]只要等于dp[i][j]+1就可以了。



tips:

   怎么 思考呢 ,首先因为si+1=tj+1,显然si和tj+1,si+1和 tj均不相等。那么 dp[i][j+1] 和 dp[i+1][j] 其实也就等于dp[i][j]。



①要注意的是s1第i个字母在数组中的位置是s1[i-1]而不是s[i],s2同理。所以下面这个判断的是s1[i-1]==s2[j-1]  它想表达的就是s1的第i个字母与s2的第j个字母是否相等,所以与上面的递推式是一致的

1 if(  s1[i-1] == s2[j-1] )
2     dp[i][j] = dp[i-1][j-1]+1;
3 else
4     dp[i][j] = max( dp[i-1][j] , dp[i][j-1] );

其实啊 我想了想 觉得这个数组从0开始用和从1开始用 还是很有讲究的。

AC代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 int dp[5000][5000];
 7 char s1[5000],s2[5000];
 8 int main()
 9 {
10
11     while(~scanf("%s%s",&s1,&s2))
12     {
13         int len1=strlen(s1);
14         int len2=strlen(s2);
15         for(int i=0 ; i <= len1 ; i++)
16             dp[i][0]=0;
17         for(int j=0 ; j <= len2 ; j++)
18             dp[0][j]=0;
19
20         for(int i=1 ; i <= len1 ; i++)
21             for(int j=1 ; j <= len2 ; j++)
22         {
23             if(  s1[i-1] == s2[j-1] )
24                 dp[i][j] = dp[i-1][j-1]+1;
25             else
26                 dp[i][j] = max( dp[i-1][j] , dp[i][j-1] );
27         }
28         printf("%d\n", dp[len1][len2] );
29     }
30     return 0;
31 }
时间: 2024-10-24 18:12:09

hdu 1159 Common Subsequence(dp 最长公共子序列问题LCS)的相关文章

hdu 1159 Common Subsequence(最长公共子序列,DP)

题意: 两个字符串,判断最长公共子序列的长度. 思路: 直接看代码,,注意边界处理 代码: char s1[505], s2[505]; int dp[505][505]; int main(){ while(scanf("%s%s",s1,s2)!=EOF){ int l1=strlen(s1); int l2=strlen(s2); mem(dp,0); dp[0][0]=((s1[0]==s2[0])?1:0); rep(i,1,l1-1) if(s1[i]==s2[0]) dp

hdu 1159 Common Subsequence(最长公共子序列)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 37551    Accepted Submission(s): 17206 Problem Description A subsequence of

hdu 1159 Common Subsequence (最长公共子序列)

Common Subsequence Problem Description A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, ..., xm> another sequence Z = <z1, z2, ..., zk> is a subsequence of X if

POJ 1458 &amp;&amp; HDU 1159 Common Subsequence (最長公共子序列)dp

鏈接:http://poj.org/problem?id=1458 Description: A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = < x1, x2, ..., xm > another sequence Z = < z1, z2, ..., zk > is a subseque

杭电1159 Common Subsequence【最长公共子序列】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 解题思路:任意先给出两个字符串 abcfbc abfcab,用dp[i][j]来记录当前最长的子序列,则如果有x[i]与y[j]相等的话,则相当于公共子序列的长度在dp[i-1][j-1]上增加1, 如果x[i]与y[j]不相等的话,那么dp[i][j]就取得dp[i][j-1]和dp[i-1][j]中的最大值即可.时间复杂度为O(mn) 反思:大概思路想出来之后,因为dp数组赋初值调了很久,

HDU 1159:Common Subsequence(最长公共子序列)

Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 23108    Accepted Submission(s): 10149 Problem Description A subsequence of a given sequence is the given sequence with some e

HDU 1159 Common Subsequence --- DP入门之最长公共子序列

题目链接 基础的最长公共子序列 #include <bits/stdc++.h> using namespace std; const int maxn=1e3+5; char c[maxn],d[maxn]; int dp[maxn][maxn]; int main() { while(scanf("%s%s",c,d)!=EOF) { memset(dp,0,sizeof(dp)); int n=strlen(c); int m=strlen(d); for(int i

uva 10405 Longest Common Subsequence (最长公共子序列)

uva 10405 Longest Common Subsequence Sequence 1: Sequence 2: Given two sequences of characters, print the length of the longest common subsequence of both sequences. For example, the longest common subsequence of the following two sequences: abcdgh a

POJ 1458 Common Subsequence 【最长公共子序列】

解题思路:先注意到序列和串的区别,序列不需要连续,而串是需要连续的,先由样例abcfbc         abfcab画一个表格分析,用dp[i][j]储存当比较到s1[i],s2[j]时最长公共子序列的长度 a    b    f    c    a    b 0    0    0    0    0   0    0 a  0    1     1    1    1   1    1 b  0    1     2    2    2   2    2 c  0    1     2