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;
}
posted @ 2018-02-05 09:17  aziint  阅读(94)  评论(0编辑  收藏  举报
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.