您的位置:首页 > 其它

[区间DP] bzoj1055 [HAOI2008]玩具取名

2018-02-27 21:06 323 查看
bzoj1055 [HAOI2008]玩具取名 http://www.lydsy.com/JudgeOnline/problem.php?id=1055

比较简单的一道题

区间DP

但是网上题解有记忆化搜索但是不会

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[5][5][5],f[210][210][5];
//a:输入保证字母i和字母j可以合成看 f:第i个到第j个是否可以合成一个字母k
char ch[210];
int p(char c)
{
if (c=='W') return 1;
else if (c=='I') return 2;
else if (c=='N') return 3;
else if (c=='G') return 4;
}
int main()
{
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
int W,I,N,G;
scanf("%d%d%d%d",&W,&I,&N,&G);
for (int i=1;i<=W;i++)
{
scanf("%s",ch+1);
a[p(ch[1])][p(ch[2])][1]=1;
}
for (int i=1;i<=I;i++)
{
scanf("%s",ch+1);
a[p(ch[1])][p(ch[2])][2]=1;
}
for (int i=1;i<=N;i++)
{
scanf("%s",ch+1);
a[p(ch[1])][p(ch[2])][3]=1;
}
for (int i=1;i<=G;i++)
{
scanf("%s",ch+1);
a[p(ch[1])][p(ch[2])][4]=1;
}
scanf("%s",ch+1);
int len=strlen(ch+1);
for (int i=1;i<=len;i++)
{
f[i][i][p(ch[i])]=1;
}
for (int l=2;l<=len;l++)//枚举长度
{
for (int i=1;i<=len-l+1;i++) //枚举开头
{
int j=i+l-1;//结尾
for (int k=i;k<=j-1;k++)//枚举中间点
{
for (int z=1;z<=4;z++)//最终合成
{
for (int x=1;x<=4;x++)//左端合成
{
for (int y=1;y<=4;y++)//右端合成
{
if (f[i][j][z]==0)
{
if (a[x][y][z]==1&&f[i][k][x]==1&&f[k+1][j][y]==1) f[i][j][z]=1;
//输入保证xy能合成z  左端能合成x  右端能合成y
}
}
}
}
}
}
}
int bk=true;
if (f[1][len][1]) {bk=0;printf("W");}
if (f[1][len][2]) {bk=0;printf("I");}
if (f[1][len][3]) {bk=0;printf("N");}
if (f[1][len][4]) {bk=0;printf("G");}
if (bk) printf("The name is wrong!");
printf("\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: