bzoj 1055: [HAOI2008]玩具取名

DP  

/**************************************************************
    Problem: 1055
    User: lxy8584099
    Language: C++
    Result: Accepted
    Time:2176 ms
    Memory:2116 kb
****************************************************************/
 
/*
    简单DP
     f i,j,p 表示 i到j 能否用k表示出来 
     仅当 f i,k,x 表示  f k+1,j,y  且 p能变成 x,y 的时候成立
     就是 n^4的转移 
*/
#include<bits/stdc++.h>
const int N=205;
using namespace std;
int mp[250],n;
int f[N][N][5];
int a,b,c,d;
int ch[N],u[N],v[N],top;
char s[10];
int main()
{
    mp['W']=1;mp['I']=2;mp['N']=3;mp['G']=4;
    scanf("%d%d%d%d",&a,&b,&c,&d);
    for(int i=1;i<=a;i++)
        scanf("%s",s),ch[++top]=mp['W'],u[top]=mp[s[0]],v[top]=mp[s[1]];
    for(int i=1;i<=b;i++)
        scanf("%s",s),ch[++top]=mp['I'],u[top]=mp[s[0]],v[top]=mp[s[1]];
    for(int i=1;i<=c;i++)
        scanf("%s",s),ch[++top]=mp['N'],u[top]=mp[s[0]],v[top]=mp[s[1]];
    for(int i=1;i<=d;i++)
        scanf("%s",s),ch[++top]=mp['G'],u[top]=mp[s[0]],v[top]=mp[s[1]];
    scanf("%s",s+1); n=strlen(s+1);
    for(int i=1;i<=n;i++) f[i][i][mp[s[i]]]=1;
    for(int len=2;len<=n;len++)
        for(int l=1;l<=n-len+1;l++)
        {
            int r=l+len-1;
            for(int k=l;k<=r;k++)
                for(int i=1;i<=top;i++)
                    f[l][r][ch[i]]|=(f[l][k][u[i]]&&f[k+1][r][v[i]]);
        }
    bool p=1;
    if(f[1][n][1]) printf("W"),p=0;
    if(f[1][n][2]) printf("I"),p=0;
    if(f[1][n][3]) printf("N"),p=0;
    if(f[1][n][4]) printf("G"),p=0;
    if(p) puts("The name is wrong!");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lxy8584099/p/10301813.html