您的位置:首页 > 其它

BZOJ1055: [HAOI2008]玩具取名 区间DP

2017-03-13 21:34 453 查看
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1055

f[i][j][k]表示区间i,j能否合成出来字符k,其中k=1,2,3,4分别代表字母W,I,N,G,然后写一个自带64倍常数的区间DP就可以了#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=205;
int n,W,I,N,G;
bool b[M][M][5],f[M][M][5];
char c[M];
int get(char c)
{
if(c=='W') return 1;
else if(c=='I') return 2;
else if(c=='N') return 3;
else return 4;
}
char nget(int x)
{
if(x==1) return 'W';
else if(x==2) return 'I';
else if(x==3) return 'N';
else return 'G';
}
int main()
{
scanf("%d%d%d%d",&W,&I,&N,&G);
char s[3];
int x,y;
for(int i=1;i<=W;i++)
{
scanf("%s",s+1);
x=get(s[1]);
y=get(s[2]);
b[x][y][1]=true;
}
for(int i=1;i<=I;i++)
{
scanf("%s",s+1);
x=get(s[1]);
y=get(s[2]);
b[x][y][2]=true;
}
for(int i=1;i<=N;i++)
{
scanf("%s",s+1);
x=get(s[1]);
y=get(s[2]);
b[x][y][3]=true;
}
for(int i=1;i<=G;i++)
{
scanf("%s",s+1);
x=get(s[1]);
y=get(s[2]);
b[x][y][4]=true;
}
scanf("%s",c+1);
int n=strlen(c+1);
for(int i=1;i<=n;i++) f[i][i][get(c[i])]=1;

for(int l=2;l<=n;l++)
for(int i=1;i+l-1<=n;i++)
{
int j=i+l-1;
for(int k=i;k<=j;k++)
for(int w=1;w<=4;w++)
for(int p=1;p<=4;p++)
for(int q=1;q<=4;q++)
f[i][j][w]|=b[p][q][w]&f[i][k][p]&f[k+1][j][q];
}
bool flag=false;
for(int i=1;i<=4;i++)
if(f[1]
[i]) {flag=true;printf("%c",nget(i));}
if(!flag) puts("The name is wrong!");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  BZOJ 区间DP