链接:点击打开链接
题意:给你两个单词,然后把两个单词拼接成一个新单词,使得新单词的子序列中包含两个单词,并且要使这个新单词最短
代码:
#include <vector>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
int dp[505][505];
vector<int> path[505][505];
int main(){
char s1[505],s2[505];
int i,j,p,q,st,len1,len2,siz;
char tmp;
while(scanf("%s%s",s1+1,s2+1)!=EOF){
memset(dp,0,sizeof(dp));
len1=strlen(s1+1);
len2=strlen(s2+1);
for(i=0;i<=len1;i++)
for(j=0;j<=len2;j++)
path[i][j].clear();
for(i=1;i<=len1;i++)
for(j=1;j<=len2;j++){
if(s1[i]==s2[j]&&dp[i-1][j-1]+1>dp[i][j]){
dp[i][j]=dp[i-1][j-1]+1;
path[i][j]=path[i-1][j-1];
path[i][j].push_back(i);
}
else if(dp[i-1][j]>=dp[i][j-1]){
dp[i][j]=dp[i-1][j];
path[i][j]=path[i-1][j];
}
else if(dp[i-1][j]<dp[i][j-1]){
dp[i][j]=dp[i][j-1];
path[i][j]=path[i][j-1];
}
} //用path记录路径
siz=path[len1][len2].size();
st=0,p=q=1;
while(st<siz){
tmp=s1[path[len1][len2][st]];
while(s1[p]!=tmp&&p<=len1){
printf("%c",s1[p]);
p++;
}
while(s2[q]!=tmp&&q<=len2){
printf("%c",s2[q]);
q++;
}
if(s1[p]==tmp&&s2[q]==tmp){
printf("%c",tmp);
p++,q++,st++;
}
} //最长公共子序列输出一次,其它正常输出
while(p<=len1)
printf("%c",s1[p++]);
while(q<=len2)
printf("%c",s2[q++]);
printf("\n");
}
return 0;
}