1055: [HAOI2008]玩具取名

首先这题只存在单字母变成两个字母,不能从双子母变成单字母。

所以进行操作得区间最多只有1~n,

考虑区间dp

令f i,j,k表示在i~j这个区间凑成 k是否可行。

用'1''2''3''4'替代'W''I''N''G'

然后转移就可以很简单得写出来

fijk |= f i,p,q1 & f i,p+1,q2

c++代码如下:

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<cctype>
#include<vector>
#define id(x) (x == 'W' ? 1 : x == 'I' ? 2 :x == 'N' ? 3 : 4)
#define rep(i,x,y) for(register int i = x;i <= y;++ i)
#define repd(i,x,y) for(register int i = x ; i >= y;-- i)
using namespace std;
template<typename T>inline void read(T&x)
{
	char c;int sign = 1;x = 0;
	do { c = getchar(); if(c == '0') sign = 1; }while(!isdigit(c));
	do { x = x * 10 + c - '0'; c = getchar(); }while(isdigit(c));
	x *= sign;
}

const int N = 201;
int f[N][N][N],t[5][N],a[N],x[5];
char s[N];

bool dfs(int l,int r,int k)
{
	if(l > r) return true;
	if(l == r) return f[l][r][k] = k == a[l];
	if(~f[l][r][k]) return f[l][r][k];
	
	rep(i,1,x[k])
		rep(j,l,r - 1)
			if(dfs(l,j,t[k][i]/10) && dfs(j + 1,r,t[k][i]%10))
				return f[l][r][k] = 1;
	return f[l][r][k] = 0;
}

int main()
{
	memset(f,-1,sizeof f);
	read(x[1]); read(x[2]); read(x[3]); read(x[4]);
	rep(j,1,4) rep(i,1,x[j])
	{
		scanf("%s",s);
		t[j][i] = id(s[0]) * 10 + id(s[1]);
	}
	scanf("%s",s + 1);
	int len = strlen(s + 1);
	rep(i,1,len) a[i] = id(s[i]);
	bool flag = 0;
	rep(i,1,4) if(dfs(1,len,i)) flag = 1,printf(i == 1 ? "W" : i == 2 ? "I" : i == 3 ? "N" : "G");
	
	if(!flag) puts("The name is wrong!");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值