bzoj1055 [HAOI2008]玩具取名 dp

123 篇文章 0 订阅

Description


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

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

Solution


一开始还以为是什么奇怪的图论题,我果然菜啊

设f[i,j,k]表示i到j能否用k表示,然后暴力转移即可

Code


#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define fi first
#define se second

typedef std:: pair <int,int> pair;
const int N=205;

bool f[N][N][4];
char str[N];
pair a[N][N];
int cnt[N];

int get(char x) {
    if (x=='W') return 0;
    if (x=='I') return 1;
    if (x=='N') return 2;
    if (x=='G') return 3;
}

int main(void) {
    rep(i,0,3) scanf("%d",&cnt[i]);
    rep(i,0,3) {
        rep(j,1,cnt[i]) {
            char ch[2]; scanf("%s",ch);
            a[i][j]=pair(get(ch[0]),get(ch[1]));
        }
    }
    scanf("%s",str+1); int n=strlen(str+1);
    rep(i,1,n) f[i][i][get(str[i])]=1;
    rep(len,1,n) {
        rep(i,1,n-len) {
            int j=i+len;
            rep(k,0,3) rep(l,i,j) {
                if (f[i][j][k]) break;
                rep(t,1,cnt[k]) {
                    if (f[i][j][k]) break;
                    f[i][j][k]|=f[i][l][a[k][t].fi]&f[l+1][j][a[k][t].se];
                }
            }
        }
    }
    if (f[1][n][0]) putchar('W');
    if (f[1][n][1]) putchar('I');
    if (f[1][n][2]) putchar('N');
    if (f[1][n][3]) putchar('G');
    if (!f[1][n][0]&&!f[1][n][1]&&!f[1][n][2]&&!f[1][n][3]) {
        puts("The name is wrong!");
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值