HDU 1501 Zipper
问前两个字符串是否能组合成第三个字符串,保持原字符串的顺序。
看到别人的代码有两种做法:
1、DFS
hash数组标记足迹,可以减少重复搜索的次数。
这个代码太过巧妙,体会体会再体会。。
1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 bool hash[205][205]; 8 char s1[205], s2[205], s3[410]; 9 10 bool DFS(int a, int b, int c) 11 { 12 if(s3[c] == '\0') 13 return true; 14 if(hash[a][b]) 15 return false; 16 hash[a][b] = true; 17 if(s1[a] == s3[c] && DFS(a+1, b, c+1)) 18 return true; 19 if(s2[b] == s3[c] && DFS(a, b+1, c+1)) 20 return true; 21 return false; 22 } 23 24 int main(void) 25 { 26 #ifdef LOCAL 27 freopen("1501in.txt", "r", stdin); 28 #endif 29 30 int T, kase; 31 scanf("%d", &T); 32 for(kase = 1; kase <= T; ++kase) 33 { 34 printf("Data set %d: ", kase); 35 cin >> s1 >> s2 >> s3; 36 memset(hash, false, sizeof(hash)); 37 if(DFS(0, 0, 0)) 38 printf("yes\n"); 39 else 40 printf("no\n"); 41 42 } 43 return 0; 44 }
2、DP
最优子结构分析:如上例,如果A、B可以组成C,那么,C最后一个字母e,必定是 A 或 C 的最后一个字母组成。
C去除除最后一位,就变成是否可以求出 A-1和B 或者 A与B-1 与 是否可以构成 C-1
状态转移方程:
用dp[i][j] 表示 表示A前 i 为 和B 前j 位是否可以组成 C的前i+j位
用dp[i][j] 表示 表示A前 i 为 和B 前j 位是否可以组成 C的前i+j位
dp[i][j]= (dp[i-1][j]&&(a[i]==c[i+j]))||(dp[i][j-1]&&(b[j]==c[i+j]))
1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 bool dp[205][205]; 8 char s1[205], s2[205], s3[410]; 9 10 int main(void) 11 { 12 #ifdef LOCAL 13 freopen("1501in.txt", "r", stdin); 14 #endif 15 16 int T, kase; 17 scanf("%d", &T); 18 for(kase = 1; kase <= T; ++kase) 19 { 20 printf("Data set %d: ", kase); 21 cin >> (s1+1) >> (s2+1) >> (s3+1); 22 int len1, len2, len3; 23 len1 = strlen(s1+1); 24 len2 = strlen(s2+1); 25 len3 = strlen(s3+1); 26 if(len1 + len2 != len3) 27 { 28 printf("no\n"); 29 continue; 30 } 31 memset(dp, false, sizeof(dp)); 32 int i, j; 33 i = 0; 34 while(s1[i] == s3[i]) //处理边界 35 dp[i++][0] = true; 36 i = 0; 37 while(s2[i] == s3[i]) 38 dp[0][i++] = true; 39 for(i = 1; i <= len1; ++i) 40 for(j = 1; j <= len2; ++j) 41 dp[i][j] = ((dp[i-1][j] && s1[i] == s3[i+j]) 42 || (dp[i][j-1] && s2[j] == s3[i+j])); 43 44 45 if(dp[len1][len2]) 46 printf("yes\n"); 47 else 48 printf("no\n"); 49 } 50 return 0; 51 }