bzoj1055 ||P4290 [HAOI2008]玩具取名

链接

luogu
bzoj

思路

区间dp
然后\(f[i][j][k]\) 区间\([i,j]\)能否变成\(k\)字符 (字符当然得转化一下)
字符的个数不多,直接暴力\(check\),暴力转移就行,\(%%gzy\)
区间dp还是挺套路模板
只不过看着恶心,其实真不恶心

for枚举长度
      for枚举起点
            计算终点
            for枚举中点
                   大力转移

代码

/**************************************************************
    Problem: 1055
    User: 3010651817
    Language: C++
    Result: Accepted
    Time:404 ms
    Memory:1500 kb
****************************************************************/
 
#include <bits/stdc++.h>
#define NO puts("The name is wrong!")
using namespace std;
const int maxn=207;
char Q[5]= {'\0','W','I','N','G'},s[maxn];
bool z[5][5][5];
int n,zhong[5],cnt;
bool f[maxn][maxn][5];
map<string,int> a;
int calc(char zz) {
    if(zz=='W') return 1;
    if(zz=='I') return 2;
    if(zz=='N') return 3;
    return 4;
}
int main() {
    for(int i=1; i<=4; ++i) scanf("%d",&zhong[i]);
    for(int i=1; i<=4; ++i) {
        char a[3];
        for(int j=1; j<=zhong[i]; ++j) {
            scanf("%s",a);
            z[i][calc(a[0])][calc(a[1])]=1;
        }
    }
    scanf("%s",s+1);
    n=strlen(s+1);
    for(int i=1; i<=n; ++i) {
        f[i][i][calc(s[i])]=1;
    }
    for(int len=1; len<n; ++len) {
        //长度
        for(int i=1; i<=n; ++i) {
            //起点
            int j=i+len;
            if(j>n) break; //终点
            for(int k=i; k<j; ++k) {
                //中点
                for(int i_=1; i_<=4; ++i_) {
                    if(f[i][k][i_])
                    //枚举并且chenk(i,k)
                        for(int j_=1; j_<=4; ++j_) {
                            if(f[k+1][j][j_]) {
                                //枚举并且check(k+1,j)
                                for(int k_=1; k_<=4; ++k_) {
                                    if(z[k_][i_][j_]==1) {
                                        //合并
                                        f[i][j][k_]=1;
                                    }
                                }
                            }
                        }
                }
            }
        }
    }
    for(int i=1; i<=4; ++i) {
        if(f[1][n][i]) {
            cnt++;
            printf("%c",Q[i]);
        }
    }
    if(!cnt) NO;
    return 0;
}
posted @ 2018-10-15 10:45  ComplexPug  阅读(149)  评论(6编辑  收藏  举报