zoukankan      html  css  js  c++  java
  • BZOJ 1055 区间DP

    1055: [HAOI2008]玩具取名

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1144  Solved: 668
    [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
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<vector>
    using namespace std;
    #define maxn 201
    vector<int > mp[maxn];
    int a,b,c,d,sum;
    char ch[3],s[201];
    int dp[201][201][101];
    char next[400];
    int str[555];
    void stt(char a[])
    {
        sum=0;
        if(a[0]=='W')
        {
            sum+=1;
        }else if(a[0]=='I')sum+=2;else if(a[0]=='N')sum+=3;else if(a[0]='G')sum+=4;
        sum*=10;
            if(a[1]=='W')
        {
            sum+=1;
        }else if(a[1]=='I')sum+=2;else if(a[1]=='N')sum+=3;else if(a[1]='G')sum+=4;
    }
    int  main()
    {
    
       next[1]='W';str['W']=1;
       next[2]='I';str['I']=2;
       next[3]='N';str['N']=3;
       next[4]='G';str['G']=4;
         scanf("%d%d%d%d",&a,&b,&c,&d);
         for(int i=1;i<=a;i++)
         {
             scanf("%s",ch);
             stt(ch);
             //cout<<sum<<endl;
             mp[sum].push_back(1);
         }
         for(int i=1;i<=b;i++)
         {
             scanf("%s",ch);
             stt(ch);
             mp[sum].push_back(2);
         }
          for(int i=1;i<=c;i++)
         {
             scanf("%s",ch);
             stt(ch);
            mp[sum].push_back(3);
         }
          for(int i=1;i<=d;i++)
         {
             scanf("%s",ch);
             stt(ch);
             mp[sum].push_back(4);
         }
         scanf("%s",s);
         memset(dp,0,sizeof(dp));
         for(int i=0;i<strlen(s);i++){
            dp[i][i][str[s[i]]]=1;
         }
         int n=strlen(s);
        for(int l=2;l<=n;l++)
        {
            for(int i=0;i<n-l+1;i++)
            {
                for(int k=i;k<i+l-1;k++)
                {
                    for(int j=1;j<=4;j++)
                        for(int h=1;h<=4;h++)
                    {
                        if(dp[i][k][j]&&dp[k+1][i+l-1][h])
                        {
                            for(int f=0;f<mp[j*10+h].size();f++)
                            {
                                dp[i][i+l-1][mp[j*10+h][f]]=1;
                            }
                        }
                    }
                }
            }
        }
        int flag=0;
        for(int i=1;i<=4;i++)
            if(dp[0][n-1][i])cout<<next[i],flag=1;
            if(!flag)cout<<"The name is wrong!";
        cout<<endl;
        return 0;
    }
    代码君
  • 相关阅读:
    23种设计模式全解析
    Dubbo
    存储过程——存储过程与函数(四)
    ADO.NET- 基础总结及实例介绍
    存储过程——存储过程与视图(三)
    存储过程——增删改(二)
    简易三层架构详解
    Ado.Net实现简易(省、市、县)三级联动查询,还附加Access数据
    存储过程——介绍(一)
    SqlBulkCopy批量写入25万条数据只需3s
  • 原文地址:https://www.cnblogs.com/zxhl/p/4797824.html
Copyright © 2011-2022 走看看