hdu1501 字符串拼接(dfs+剪枝)
题目链接:Zipper
该题有两种解法,一种就是使用dfs,另一种是动态规划(另一种解法之后补
该题卡了一个时限,在使用dfs的时候注意需要剪枝(不减的话会超时
【剪枝这一个地方想了挺长时间的,是我自己尝试的数据太水了👎
搜索思路:将a,b,c串只有三种情况,1.c串的当前字母属于a串,2.c串的当前字母属于b串,3.都不属于a,b两串,前两种情况向前进,最后一种不成立,由于我想的数据过于简单,递归次数很少。当a,b串的相同字母很多的时候就会产生多个相同的递归,需要将其剪掉。
dfs:
char a[1005],b[1005],c[2010]; int vis[1005][1005]; void dfs(int a1,int b1,int c1) { if(c1==strlen(c)) { flag=1; //当匹配到c串的末尾记录之后输出 return; } if(vis[a1][b1]==1) //用vis数组来表示这条分支是否被走过,如果走过就不再重复向下搜索 { //cout<<"hi."<<endl; //可以尝试一下多字母相同的ab串,体验一下递归的次数 return; } vis[a1][b1]=1; if(a[a1]==c[c1]) { dfs(a1+1,b1,c1+1); } if(b[b1]==c[c1]) { dfs(a1,b1+1,c1+1); } }
完整代码:
#include<bits/stdc++.h> using namespace std; int n,flag=0; char a[1005],b[1005],c[2010]; int vis[1005][1005]; void dfs(int a1,int b1,int c1) { if(c1==strlen(c)) { flag=1; return; } if(vis[a1][b1]==1) { //cout<<"hi."<<endl; return; } vis[a1][b1]=1; if(a[a1]==c[c1]) { dfs(a1+1,b1,c1+1); } if(b[b1]==c[c1]) { dfs(a1,b1+1,c1+1); } } int main() { cin>>n; int temp=1; while(n--) { memset(vis,0,sizeof(vis)); flag=0; cin>>a>>b>>c; dfs(0,0,0); cout<<"Data set "<<temp++<<": "; if(flag) { cout<<"yes"<<endl; } else { cout<<"no"<<endl; } } return 0; }