bzoj1055 [HAOI2008]玩具取名
Description
某人有一套玩具,并想法给玩具命名。首先他选择WING四个字母中的任意一个字母作为玩具的基本名字。然后他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够扩充得很长。现在,他想请你猜猜某一个很长的名字,最初可能是由哪几个字母变形过来的。
\(len \leqslant 200\), \(W, I, N, G \leqslant 16\)
Solution
傻逼区间dp。然而我还看错题 + 数组开小调错20min。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
inline int read() {
int x = 0, flag = 1; char ch = getchar();
while (ch > '9' || ch < '0') { if (ch == '-') flag = -1; ch = getchar(); }
while (ch <= '9' && ch >= '0') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * flag;
}
#define N 201
#define rep(ii, aa, bb) for (int ii = aa; ii <= bb; ii++)
#define ll long long
const char chVal[] = { '?', 'W', 'I', 'N', 'G' };
char chKey[256];
int len;
int f[N][N][5];
int chgTot[5];
char chgWay[5][17][3];
char str[N];
int dp(int l, int r, int x) {
if (l == r) return f[l][r][x] = (str[l] == chVal[x]);
int &ans = f[l][r][x];
if (ans != -1) return ans;
rep(i, 1, chgTot[x]) rep(j, l, r - 1)
if (dp(l, j, chKey[chgWay[x][i][1]]) && dp(j + 1, r, chKey[chgWay[x][i][2]]))
return ans = 1;
return ans = 0;
}
int main() {
chKey['W'] = 1; chKey['I'] = 2; chKey['N'] = 3; chKey['G'] = 4;
rep(i, 1, 4) scanf("%d", &chgTot[i]);
rep(i, 1, 4) rep(j, 1, chgTot[i]) scanf("%s", chgWay[i][j] + 1);
scanf("%s", str + 1); len = strlen(str + 1);
bool flag = 0;
memset(f, -1, sizeof f);
rep(i, 1, 4) if (dp(1, len, i)) putchar(chVal[i]), flag = 1;
if (!flag) puts("The name is wrong!");
return 0;
}