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; }