您的位置:首页 > 其它

BZOJ 1055 区间DP

2015-09-10 14:45 316 查看

1055: [HAOI2008]玩具取名

Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 1144 Solved: 668
[Submit][Status][Discuss]

Description

某人有一套玩具,并想法给玩具命名。首先他选择WING四个字母中的任意一个字母作为玩具的基本名字。然后他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够扩充得很长。现在,他想请你猜猜某一个很长的名字,最初可能是由哪几个字母变形过来的。

Input

第一行四个整数W、I、N、G。表示每一个字母能由几种两个字母所替代。接下来W行,每行两个字母,表示W可以用这两个字母替代。接下来I行,每行两个字母,表示I可以用这两个字母替代。接下来N行,每行两个字母,表示N可以用这两个字母替代。接下来G行,每行两个字母,表示G可以用这两个字母替代。最后一行一个长度不超过Len的字符串。表示这个玩具的名字。

Output

一行字符串,该名字可能由哪些字母变形而得到。(按照WING的顺序输出)如果给的名字不能由任何一个字母变形而得到则输出“The name is wrong!”

Sample Input

1 1 1 1

II

WW

WW

IG

IIII

Sample Output

IN

HINT

W可以变成II所以IIII可以缩成WW IN均能变成WW所以WW又可以缩成I或者N 所以最终答案应该按照“WING”的顺序输出IN

[数据范围]

100%数据满足Len<=200,W、I、N、G<=16

题解:暴力区间DP

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 201
vector<int > mp[maxn];
int a,b,c,d,sum;
char ch[3],s[201];
int dp[201][201][101];
char next[400];
int str[555];
void stt(char a[])
{
sum=0;
if(a[0]=='W')
{
sum+=1;
}else if(a[0]=='I')sum+=2;else if(a[0]=='N')sum+=3;else if(a[0]='G')sum+=4;
sum*=10;
if(a[1]=='W')
{
sum+=1;
}else if(a[1]=='I')sum+=2;else if(a[1]=='N')sum+=3;else if(a[1]='G')sum+=4;
}
int  main()
{

next[1]='W';str['W']=1;
next[2]='I';str['I']=2;
next[3]='N';str['N']=3;
next[4]='G';str['G']=4;
scanf("%d%d%d%d",&a,&b,&c,&d);
for(int i=1;i<=a;i++)
{
scanf("%s",ch);
stt(ch);
//cout<<sum<<endl;
mp[sum].push_back(1);
}
for(int i=1;i<=b;i++)
{
scanf("%s",ch);
stt(ch);
mp[sum].push_back(2);
}
for(int i=1;i<=c;i++)
{
scanf("%s",ch);
stt(ch);
mp[sum].push_back(3);
}
for(int i=1;i<=d;i++)
{
scanf("%s",ch);
stt(ch);
mp[sum].push_back(4);
}
scanf("%s",s);
memset(dp,0,sizeof(dp));
for(int i=0;i<strlen(s);i++){
dp[i][i][str[s[i]]]=1;
}
int n=strlen(s);
for(int l=2;l<=n;l++)
{
for(int i=0;i<n-l+1;i++)
{
for(int k=i;k<i+l-1;k++)
{
for(int j=1;j<=4;j++)
for(int h=1;h<=4;h++)
{
if(dp[i][k][j]&&dp[k+1][i+l-1][h])
{
for(int f=0;f<mp[j*10+h].size();f++)
{
dp[i][i+l-1][mp[j*10+h][f]]=1;
}
}
}
}
}
}
int flag=0;
for(int i=1;i<=4;i++)
if(dp[0][n-1][i])cout<<next[i],flag=1;
if(!flag)cout<<"The name is wrong!";
cout<<endl;
return 0;
}


代码君
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: