BZOJ 1055 [HAOI2008]玩具取名

题目链接

一个人首先给一个玩具取名为WING中的一个字符,且W,I,N,G分别可以变成w,i,n,g种两个WING中的字符,给出玩具最终的名字,问最初的名字可以为那些字符

定义dp[l][r][k]为[l,r]是否可以变成一种第k个字符

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int wing[4]; char WING[4][20][5];
char s[205];
int f[205][205][4];
int arc(char c) {
	switch(c) {
		case 'W': return 0;
		case 'I': return 1;
		case 'N': return 2;
		case 'G': return 3;
	}
}
int DP(int l, int r, int k) {
	if(l == r) return arc(s[l]) == k;
	int & res = f[l][r][k];
	if(res != -1) return res;
	res = false;
	for(int i = l; i < r; i++) {
		for(int j = 0; j < wing[k]; j++)
		  res |= DP(l, i, arc(WING[k][j][0])) 
			  && DP(i + 1, r, arc(WING[k][j][1]));
	}
	return res;
}
int main() {
	for(int i = 0; i < 4; i++) scanf("%d", &wing[i]);
	for(int i = 0; i < 4; i++) 
	  for(int j = 0; j < wing[i]; j++) 
		scanf("%s", WING[i][j]);
	scanf("%s", s);
	int len = strlen(s);
	memset(f, -1, sizeof(f));
	bool ans = 1;
	if(DP(0, len - 1, 0)) putchar('W'), ans = 0;
	if(DP(0, len - 1, 1)) putchar('I'), ans = 0;
	if(DP(0, len - 1, 2)) putchar('N'), ans = 0;
	if(DP(0, len - 1, 3)) putchar('G'), ans = 0;
	if(ans) printf("The name is wrong!");
	putchar('\n');
	return 0;
}
posted @ 2018-05-20 20:52  LJZ_C  阅读(115)  评论(0编辑  收藏  举报