zoukankan      html  css  js  c++  java
  • BZOJ1055: [HAOI2008]玩具取名[区间DP]

    1055: [HAOI2008]玩具取名

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1588  Solved: 925
    [Submit][Status][Discuss]

    Description

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

    Input

      第一行四个整数W、I、N、G。表示每一个字母能由几种两个字母所替代。接下来W行,每行两个字母,表示W可
    以用这两个字母替代。接下来I行,每行两个字母,表示I可以用这两个字母替代。接下来N行,每行两个字母,表示N
    可以用这两个字母替代。接下来G行,每行两个字母,表示G可以用这两个字母替代。最后一行一个长度不超过Len的
    字符串。表示这个玩具的名字。

    Output

      一行字符串,该名字可能由哪些字母变形而得到。(按照WING的顺序输出)如果给的名字不能由任何一个字母
    变形而得到则输出“The name is wrong!”

    Sample Input

    1 1 1 1
    II
    WW
    WW
    IG
    IIII

    Sample Output

    IN

    HINT

    W可以变成II所以IIII可以缩成WW IN均能变成WW所以WW又可以缩成I或者N 所以最终答案应该按照“WING”的顺序

    输出IN 

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

    区间DP
    注意所有的字符都是WING之一........................
    d[i][j][k]表示i到j能否变成编号为k的字符
    用了个mp和fmp
    区间DP用记忆化搜索比较方便
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    using namespace std;
    const int N=205;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int num[5],mp[255];
    char a[5][17][3],s[N],fmp[5]={' ','W','I','N','G'};
    int d[N][N][27];
    int dp(int l,int r,int k){    
        int &ans=d[l][r][k];
        if(ans!=-1) return ans;
        if(l==r) return s[l]==fmp[k];
        ans=0;
        for(int i=l;i<=r-1;i++)
            for(int j=1;j<=num[k];j++)
                if(dp(l,i,mp[a[k][j][1]])&&dp(i+1,r,mp[a[k][j][2]])) return ans=1;
        return ans;
    }
    int main(){
        for(int i=1;i<=4;i++) num[i]=read();
        for(int i=1;i<=4;i++)
            for(int j=1;j<=num[i];j++) scanf("%s",a[i][j]+1);
        scanf("%s",s+1);
        memset(d,-1,sizeof(d));
        mp['W']=1;mp['I']=2;mp['N']=3;mp['G']=4;
        int len=strlen(s+1),flag=0;
        for(int k=1;k<=4;k++) 
            if(dp(1,len,k)) putchar(fmp[k]),flag=1;
        if(!flag) printf("The name is wrong!");
    }
  • 相关阅读:
    leetcode 29-> Divide Two Integers without using multiplication, division and mod operator
    ros topic 发布一次可能会接收不到数据
    python中的print()、str()和repr()的区别
    python 部分函数
    uiautomatorviewer错误 unable toconnect to adb
    pyqt 不规则形状窗口显示
    appium 计算器demo
    Spring 3.0 注解注入详解
    Spring Autowire自动装配
    restful 学习地址
  • 原文地址:https://www.cnblogs.com/candy99/p/5960393.html
Copyright © 2011-2022 走看看