BZOJ1055: [HAOI2008]玩具取名

题解:

一道简单的dp题。定义f[i][j][c]表示i~j这一区间中的所有字母能否缩成c这一字母。转移就是:f[i][j][c]=f[i][k][c1]&& f[k+1][c2]&&(c1c2>>c,i<=k<=j)。字符串处理一下即可。
代码如下:

#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
const int maxn=205;
int n,a[5][maxn],hsh[5][maxn];
bool f[maxn][maxn][6];
char s[maxn],p[maxn];
int get(char ch){
    if (ch=='W') return 1;
    else if (ch=='I') return 2;
    else if (ch=='N') return 3;
    else if (ch=='G') return 4; 
}
int read(){
    int x=0; char ch=getchar();
    while (ch!='W'&&ch!='I'&&ch!='N'&&ch!='G') ch=getchar();
    return get(ch);
}
int main(){
    p[1]='W',p[2]='I',p[3]='N',p[4]='G';
    scanf("%d %d %d %d",&a[1][0],&a[2][0],&a[3][0],&a[4][0]);
    for (int i=1;i<=4;i++)
    for (int j=1;j<=a[i][0];j++) a[i][j]=read()*10+read(),hsh[i][a[i][j]]=i;
    scanf("%s",s+1);
    n=strlen(s+1);
    for (int i=1;i<=n;i++) f[i][i][get(s[i])]=1;
    for (int l=2;l<=n;l++)
    for (int i=1;i<=n-l+1;i++) {
        int j=i+l-1;
        for (int k=i;k<j;k++)
        for (int k1=1;k1<=4;k1++)
        for (int k2=1;k2<=4;k2++)
        for (int k3=1;k3<=4;k3++)
        if (f[i][k][k1]==1&&f[k+1][j][k2]==1&&hsh[k3][k1*10+k2]>0) f[i][j][k3]=1;
    }
    bool check=0;
    for (int i=1;i<=4;i++) if (f[1][n][i]==1) {printf("%c",p[i]); check=1;}
    if (check==0) printf("The name is wrong!\n");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值