題意:給出兩串,兩串順序不變看能否組成第三個串。
此題深搜和DP都能解決:
深搜的話需要幾個強有力剪枝條件
1、 第三個串最后一個字符要么是串1的最后一個字符,要么是串2的最后一個字符
2、 按照串1的順序對串3進行搜索,若不匹配則該字符必是串2的下一個字符。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char first[202],second[202],third[402],Left[401];
int sign[402];
bool flag;
int check()
{
int i,count=0;
int k=strlen(third);
for(i=0;i<k;i++)
if(!sign[i]) Left[count++]=third[i];
Left[count]='\0';
if(strcmp(Left,second)==0) return 1;
return 0;
}
int dfs(int f,int s,int t)
{
if(f>=strlen(first))
{
if(check()) flag=true;
return 0;
}
if(flag) return 0;
if(first[f]==third[s])
{
sign[s]=1;
if(s<strlen(third)) dfs(f+1,s+1,t);
sign[s]=0;
}
else
{
if(third[s]!=second[t]) return 0;//剪枝2
}
if(!flag && s<strlen(third)) dfs(f,s+1,t+1);
return 0;
}
int main()
{
int len1,len2,len3,Case,count=0;
scanf("%d",&Case);
while(Case--)
{
count++;
flag=false;
scanf("%s %s %s",first,second,third);
memset(sign,0,sizeof(sign));
len1=strlen(first);
len2=strlen(second);
len3=strlen(third);
if(len1+len2!=len3)
{
printf("Data set %d: no\n",count);
continue;
}
if(third[len3-1]!=first[len1-1] && third[len3-1]!=second[len2-1])// 剪枝1
{
printf("Data set %d: no\n",count);
continue;
}
dfs(0,0,0);
if(flag)
printf("Data set %d: yes\n",count);
else
printf("Data set %d: no\n",count);
}
return 0;
}
若用DP來作先定義res[i][j]=1表示串1前i個字符和串2的前j個字符能組成串3的前i+j個字符,res[i][j]=0則不能。
狀態轉移方程如下:
Res[i][j]= (third[i+j]==first[i] && res[i-1][j]==1) ||(third[i+j]==second[j]&&res[i][j-1]==1)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char first[201],second[201],third[401];
int res[201][201];
int init(int n,int m)
{
int i;
for(i=1;i<=m;i++)
if(second[i]==third[i]) res[0][i]=1;
else break;
for(i=1;i<=n;i++)
if(first[i]==third[i]) res[i][0]=1;
else break;
return 0;
}
int dp(int n,int m)
{
int i,j;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
if(third[i+j]==first[i] && res[i-1][j]) res[i][j]=1;
if(third[i+j]==second[j] && res[i][j-1]) res[i][j]=1;
}
if(res[n][m]) return 1;
return 0;
}
int main()
{
int n,len1,len2,count=0;;
scanf("%d",&n);
while(n--)
{
count++;
scanf("%s %s %s",first+1,second+1,third+1);
len1=strlen(first+1);
len2=strlen(second+1);
memset(res,0,sizeof(res));
init(len1,len2);
if(dp(len1,len2))
printf("Data set %d: yes\n",count);
else
printf("Data set %d: no\n",count);
}
return 0;
}
