bzoj1055 [HAOI2008]玩具取名

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1055

【题解】

简单区间dp。

f[l,r,c]表示[l,r]是否能表示成c。

# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 200 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

char str[M], fp[5] = {0, 'W', 'I', 'N', 'G'};
int m[5], n;
int s[5][20][2];
bool f[M][M][5], vis[M][M][5];
int a[M];

inline int id(char st) {
    if(st == 'W') return 1;
    if(st == 'I') return 2;
    if(st == 'N') return 3;
    if(st == 'G') return 4;
}

inline int dp(int l, int r, int c) {
    if(vis[l][r][c]) return f[l][r][c];
    if(l == r && a[l] == c) return 1;
    vis[l][r][c] = 1;
    int ret = 0;
    for (int k=l; k<r; ++k) {
        // [l, k], [k+1, r]
        for (int i=1; i<=m[c]; ++i) 
            if(dp(l, k, s[c][i][0]) && dp(k+1, r, s[c][i][1])) {
                ret = 1;
                break;
            }
        if(ret == 1) break;
    }
    return f[l][r][c] = ret;
}

int main() {
    for (int i=1; i<=4; ++i) scanf("%d", &m[i]);
    for (int i=1; i<=4; ++i) 
        for (int j=1; j<=m[i]; ++j) {
            scanf("%s", str); 
            s[i][j][0] = id(str[0]);
            s[i][j][1] = id(str[1]);
        }
    scanf("%s", str); 
    bool gg = 1;
    n = 0;
    for (int i=0; str[i]; ++i) a[++n] = id(str[i]);
    for (int i=1; i<=4; ++i) 
        if(dp(1, n, i)) {
            printf("%c", fp[i]); 
            gg = 0;
        }
    if(gg) puts("The name is wrong!");
    return 0;
}
View Code

 

posted @ 2017-05-16 10:40  Galaxies  阅读(271)  评论(0编辑  收藏  举报