[DP] BZOJ1055: [HAOI2008]玩具取名

题意

戳这里

题解

傻逼区间 DP
反着考虑,就变成每次合并两个相邻字符变成一个新字符。
f[i][j][0..3] 表示 [i,j] 到是否可以合并成某字符。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=305;
struct data{
    int m,a[20][2];
} lst[5];
int n;
bool f[maxn][maxn][4];
char a[maxn];
int hhh[300];
int main(){
    memset(hhh,255,sizeof(hhh)); hhh['W']=0; hhh['I']=1; hhh['N']=2; hhh['G']=3; 
    freopen("bzoj1055.in","r",stdin);
    freopen("bzoj1055.out","w",stdout);
    scanf("%d%d%d%d",&lst[0].m,&lst[1].m,&lst[2].m,&lst[3].m);
    for(int k=0;k<=3;k++){
        char s[4];
        for(int i=1;i<=lst[k].m;i++) scanf("%s",s), lst[k].a[i][0]=hhh[s[0]], lst[k].a[i][1]=hhh[s[1]];
    }
    scanf("%s",a+1); n=strlen(a+1);
    for(int i=1;i<=n;i++) if(0<=hhh[a[i]]&&hhh[a[i]]<=3) f[i][i][hhh[a[i]]]=true;
    for(int L=2;L<=n;L++)
     for(int i=1,j=L;j<=n;i++,j++)
      for(int k=0;k<=3;k++){ //f[i][j][k]
        for(int t=i;t<=j-1;t++)
         for(int tt=1;tt<=lst[k].m;tt++) f[i][j][k]|=(f[i][t][lst[k].a[tt][0]]&&f[t+1][j][lst[k].a[tt][1]]);
      }
    bool pd=false;
    if(f[1][n][0]) putchar('W'), pd=true;
    if(f[1][n][1]) putchar('I'), pd=true;
    if(f[1][n][2]) putchar('N'), pd=true;    
    if(f[1][n][3]) putchar('G'), pd=true;
    if(!pd) printf("The name is wrong!");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值