题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1503
思路:这是一道最长公共子序列的题目,当然还需要记录路径。把两个字符串的最长公共字串记录下来,在递归回溯输出的时候,要是两个字符是公共子串,就只输出一次,要不是,就分别把位于相同位置的两个字符串的字符输出.......
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<math.h> 5 #include<string.h> 6 #include<vector> 7 #include<queue> 8 #include<iterator> 9 #include<vector> 10 #include<set> 11 #define dinf 0x3f3f3f3f 12 typedef long long ll; 13 14 using namespace std; 15 16 int dp[1005][1005],path[1005][1005],flag[1005]; 17 18 int main() 19 { 20 int len1,len2; 21 string str1,str2; 22 while(cin>>str1>>str2) 23 { 24 len1=str1.length(); 25 len2=str2.length(); 26 memset(dp,0,sizeof(dp)); 27 memset(path,0,sizeof(path)); 28 memset(flag,-1,sizeof(flag)); 29 for(int i=1;i<=len1;i++) 30 for(int j=1;j<=len2;j++) 31 { 32 if(str1[i-1]==str2[j-1]) 33 dp[i][j]=dp[i-1][j-1]+1; 34 else if(dp[i-1][j]>dp[i][j-1]) 35 { 36 dp[i][j]=dp[i-1][j]; 37 path[i][j]=1; 38 } 39 else 40 { 41 dp[i][j]=dp[i][j-1]; 42 path[i][j]=2; 43 } 44 } 45 for(int i=len1,j=len2;i>=1&&j>=1;) 46 { 47 if(path[i][j]==0) 48 { 49 i--; 50 j--; 51 flag[i]=j; 52 } 53 else if(path[i][j]==1) 54 i--; 55 else 56 j--; 57 } 58 int k=0; 59 for(int i=0;i<len1;i++) 60 { 61 if(flag[i]==-1) 62 cout<<str1[i]; 63 else 64 { 65 for(int j=k;j<=flag[i];j++) 66 cout<<str2[j]; 67 k=flag[i]+1; 68 } 69 } 70 for(int i=k;i<len2;i++) 71 cout<<str2[i]; 72 cout<<endl; 73 } 74 return 0; 75 }