BZOJ 1055 [HAOI2008]玩具取名

题目链接

一个人首先给一个玩具取名为WING中的一个字符,且W,I,N,G分别可以变成w,i,n,g种两个WING中的字符,给出玩具最终的名字,问最初的名字可以为那些字符

定义dp[l][r][k]为[l,r]是否可以变成一种第k个字符

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int wing[4]; char WING[4][20][5];
char s[205];
int f[205][205][4];
int arc(char c) {
    switch(c) {
        case 'W': return 0;
        case 'I': return 1;
        case 'N': return 2;
        case 'G': return 3;
    }
}
int DP(int l, int r, int k) {
    if(l == r) return arc(s[l]) == k;
    int & res = f[l][r][k];
    if(res != -1) return res;
    res = false;
    for(int i = l; i < r; i++) {
        for(int j = 0; j < wing[k]; j++)
          res |= DP(l, i, arc(WING[k][j][0])) 
              && DP(i + 1, r, arc(WING[k][j][1]));
    }
    return res;
}
int main() {
    for(int i = 0; i < 4; i++) scanf("%d", &wing[i]);
    for(int i = 0; i < 4; i++) 
      for(int j = 0; j < wing[i]; j++) 
        scanf("%s", WING[i][j]);
    scanf("%s", s);
    int len = strlen(s);
    memset(f, -1, sizeof(f));
    bool ans = 1;
    if(DP(0, len - 1, 0)) putchar('W'), ans = 0;
    if(DP(0, len - 1, 1)) putchar('I'), ans = 0;
    if(DP(0, len - 1, 2)) putchar('N'), ans = 0;
    if(DP(0, len - 1, 3)) putchar('G'), ans = 0;
    if(ans) printf("The name is wrong!");
    putchar('\n');
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ljzalc1022/p/9064525.html