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
", ++kase, flag?"yes":"no");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/shuitiangong/p/12913748.html