POJ1458 Common Subsequence

来源:互联网 发布:java 启动main 编辑:程序博客网 时间:2024/05/21 06:30

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 47372 Accepted: 19460
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 there exists a strictly increasing sequence < i1, i2, ..., ik > of indices of X such that for all j = 1,2,...,k, xij = zj. For example, Z = < a, b, f, c > is a subsequence of X = < a, b, c, f, b, c > with index sequence < 1, 2, 4, 6 >. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
Input
The program input is from the std input. Each data set in the input contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct.
Output
For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
Sample Input
abcfbc         abfcab
programming    contest 
abcd           mnp
Sample Output
4
2
0
Source
Southeastern Europe 2003


思路分析:


输入两个字符串s1,s2 , 设dp(i,j)表示s1的左边i个字符串和s2的左边j个字符串的最长公共子序列的长度(i,j从0算起),


dp(i,j)就是本题的状态。


设s1和s2字符串的长度分别为len1和len2,则
初始状态   dp(i,0)=0  i=0,1,...len1 ,  dp(0,i)=0   i=0,1,...len2


状态转移方程 
dp(i,j) = dp(i-1,j-1) + 1  , if s1[i-1]==s2[j-1]   
dp(i,j)=max(dp(i-1,j),dp(i,j-1))  , others
(0 < i <= len1, 0< j <= len2)
对状态转移方程的解释:
关于s1的左边i个字符串和s2的左边j个字符串,如果s1的左边第i个字符s1[i-1]和s2的第j个字符s2[j-1]相等的话,那么这个字符就可以作为其最后一个公共字符了,所以在dp(i-1,j-1)的基础上加1即可。
如果s1[i-1]和s2[j-1]不等的话,由于事实dp(i,j) >= dp(i-1,j)和dp(i,j) >= dp(i,j-1),
图形化表示如下:




                                   






在这里,不妨假设dp(i-1,j)>=dp(i,j-1),于是,我们可以形象化的看到dp(i,j)和dp(i,j-1)、dp(i-1,j)的大小关系。
另外,如果我们假设dp(i,j)>dp(i-1,j)(严格大于),则最长公共子序列必定以s1[i-1]必定为最长公共子序列的最后一个字符,同样由dp(i,j)>dp(i,j-1),s2[j-1]必定为最长公共子序列的最后一个字符。于是s1[i-1]等于s2[j-1],与假设矛盾,所以dp(i,j)不会严格大于dp(i-1,j),只能等于dp(i-1,j).


程序代码:
#include "iostream"
#include "cstring"
#include "string"
#include "algorithm"
using namespace std;


char s1[1000],s2[1000];
int dp[1000][1000];


int main(){

int len1,len2;
int i,j;
while(cin>>s1>>s2){

len1 = strlen(s1);
len2 = strlen(s2);
for(i = 0;i <= len1; i++) dp[i][0]=0; 
for(i = 0;i <= len2; i++) dp[0][i]=0;

for(i = 1;i <=len1; i++){
for(j = 1;j <= len2; j++ ){
if(s1[i-1]==s2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
}
}

cout << dp[len1][len2]<<endl;
}


return 0;

}


提交结果如下:


0 0
原创粉丝点击