HDU 1501 Zipper(记忆化搜索)
题目大意
两个串混在一起能不能组成第三个串,并且两个串字符之间顺序不变。
解题思路
因为两个串字符之间的原顺序不变,所以我们可以从头枚举第三个串,他的每一位肯定都是由两个串之间的一个串的某位构成的,如果不是,那么一定无解。如果枚举到某一位三个串都有共同的字符,就会出现分支,所以如果暴力搜索的话复杂度可能是指数级增长的,究其原因,还是因为重复枚举了太多相同的子问题,所以用记忆化搜索的方式将已经搜索过的状态标记下来,如果之后又到达了这个状态,那么就直接回溯就好了。
代码
const int maxn = 4e2+10;
int t, sz1, sz2, sz3, kase; bool flag;
char s1[maxn], s2[maxn], s3[maxn];
bool vis[maxn][maxn];
void dfs(int p1, int p2, int p3) {
if (p1>sz1||p2>sz2||vis[p1][p2]) return;
if (p1==sz1&&p2==sz2) {
flag = true;
return;
}
if (s1[p1]!=s3[p3]&&s2[p2]!=s3[p3]) return;
if (s1[p1]==s3[p3]) {
vis[p1][p2] = true;
dfs(p1+1, p2, p3+1);
}
if (s2[p2]==s3[p3]) {
vis[p1][p2] = true;
dfs(p1, p2+1, p3+1);
}
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%s%s%s", s1, s2, s3);
sz1 = strlen(s1); sz2 = strlen(s2); sz3 = strlen(s3);
flag = false;
dfs(0,0,0);
zero(vis);
printf("Data set %d: %s\n", ++kase, flag?"yes":"no");
}
return 0;
}