依然是字符串的dp,这回建Bool数组dp,dp[i][j]=1表示第一串的前i个和第二串的前j个匹配。
计算dp[i][j],如果a[i]与b[j]相同,则选择一个跟c匹配,只要其子问题dp[i-1][j](选a的进行匹配)或dp[i][j-1](选b的进行匹配)有一个为真就可以。
如果a[i]和b[j]不相同,则看哪一个能匹配,如果能匹配,则相应的子问题能匹配就可以,如果不能匹配,直接为false。
需要注意的是c对应的index是可以由i,j算出来的,因为在计算某一个i,j的时候前提是子问题已经计算出来了。
#include<iostream>
#include<fstream>
using namespace std;
int times;
char a[201],b[201],c[402];
bool dp[201][201];
int a_size,b_size;
void prepare(){
dp[0][0]=1;
for(int i=1;i<=a_size;i++){
if(dp[i-1][0]==1){
dp[i][0]=a[i-1]==c[i-1]?1:0;
}else{
dp[i][0]=0;
}
}
for(int i=1;i<=b_size;i++){
if(dp[0][i-1]==1){
dp[0][i]=b[i-1]==c[i-1]?1:0;
}else{
dp[0][i]=0;
}
}
}
void doDp(){
prepare();
int cindex;
for(int i=1;i<=a_size;i++){
for(int j=1;j<=b_size;j++){
cindex=i+j-1;
if(a[i-1]==b[j-1]){
if(a[i-1]!=c[cindex]){
dp[i][j]=0;
}else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}else{
if(a[i-1]==c[cindex]){
dp[i][j]=dp[i-1][j];
}else if(b[j-1]==c[cindex]){
dp[i][j]=dp[i][j-1];
}else{
dp[i][j]=0;
}
}
}
}
}
int main(){
//streambuf *backup;
// ifstream fin;
// fin.open("data.in");
// backup = cin.rdbuf(); // back up cin's streambuf
// cin.rdbuf(fin.rdbuf()); // assign file's streambuf to cin
cin>>times;
for(int i=1;i<=times;i++){
cin>>a>>b>>c;
a_size=strlen(a);
b_size=strlen(b);
doDp();
cout<<"Data set "<<i<<": "<<(dp[a_size][b_size]?"yes":"no")<<endl;
}
return 0;
}