题目链接:http://poj.org/problem?id=2192
思路分析:该问题可以看做dp问题,同时也可以使用dfs搜索求解,这里使用dp解法;
设字符串StrA[0, 1, …, n]和StrB[0,1, .., m]构成字符串Str[0, 1, … , m + n + 1];
1)状态定义:dp[i, j]表示字符串StrA[0, 1, …, i-1]和字符串StrB[0, 1, .., j-1]构成字符串Str[0, 1, …, i+j-1];
2)状态转移:如果dp[i-1][j]==1 && StrA[i-1] == Str[i+j-1]或者dp[i][j-1] == 1 && StrB[j-1] == Str[i+j-1],则dp[i][j]==1;
3)最优子结构:该问题中子结构有解才有可能使原问题有解,另外可以从该问题中看出dp与搜索的关系;
代码如下:
#include <cstring> #include <iostream> using namespace std; const int MAX_N = 200 + 10; char str_a[MAX_N], str_b[MAX_N], str[2 * MAX_N]; int dp[MAX_N][MAX_N]; int main() { int test_case, case_count = 0; int len_str_a, len_str_b; scanf("%d", &test_case); while (test_case--) { scanf("%s %s %s", str_a, str_b, str); len_str_a = strlen(str_a); len_str_b = strlen(str_b); memset(dp, 0, sizeof(dp)); for (int i = 0; i <= len_str_a; ++ i) { for (int j = 0; j <= len_str_b; ++ j) { if (i == 0 && j == 0) dp[i][j] = 1; else { if (i >= 1 && dp[i - 1][j] == 1 && str[i + j - 1] == str_a[i-1]) dp[i][j] = 1; if (j >= 1 && dp[i][j - 1] == 1 && str[i + j - 1] == str_b[j-1]) dp[i][j] = 1; } } } printf("Data set %d: ", ++case_count); if (dp[len_str_a][len_str_b] == 1) printf("yes\n"); else printf("no\n"); } return 0; }