title

「BZOJ1055」[HAOI2008] 玩具取名 - 区间动规 - 记忆化搜索

->戳我进原题

[HAOI2008]玩具取名


Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2486 Solved: 1448


### 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,写的记忆化搜索。f[i][j][k]表示区间[i,j]能否转化成k

代码

#include<cstdio>  
#include<cstring>  
#include<algorithm>  
using namespace std;  
char s[210];  
int num[5],list[210][3],tot,f[210][210][5],len;
bool p;
inline int check(char i){  
    if(i=='W') return 1;  
    if(i=='I') return 2;  
    if(i=='N') return 3;  
    if(i=='G') return 4;  
}  
int main(){
    for(register int i=1;i<=4;++i) scanf("%d\n",&num[i]);  
    for(register int i=1;i<=4;++i){
        for(register int j=1;j<=num[i];++j){  
            char ss[5];  
            scanf("%s",ss);  
            list[++tot][0]=i;
            list[tot][1]=check(ss[0]);
            list[tot][2]=check(ss[1]);
        }
        getchar();  
    }  
    gets(s+1); len=strlen(s+1);  
    for(register int i=1;i<=len;++i) f[i][i][check(s[i])]=1;  
    for(register int i=len;i>0;--i)  
        for(register int j=i+1;j<=len;++j)  
            for(register int k=i;k<j;++k)  
                for(register int l=1;l<=tot;++l)  
                    if(f[i][k][list[l][1]]&&f[k+1][j][list[l][2]]) 
                        f[i][j][list[l][0]]=1;  
    for(register int i=1;i<=4;++i)  
        if(f[1][len][i]){  
            p=1;  
            if(i==1) printf("W");  
            if(i==2) printf("I");  
            if(i==3) printf("N");  
            if(i==4) printf("G");  
        }  
    if(!p) printf("The name is wrong!\n");  
    return 0;  
}  
posted @ 2018-09-10 11:00  Horrigue_JyowYang  阅读(137)  评论(0编辑  收藏  举报