poj 2192 Zipper(区间dp)

题目链接: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;
}
posted @ 2015-05-23 22:07  Leptus  阅读(162)  评论(0编辑  收藏  举报