zoukankan      html  css  js  c++  java
  • 【BZOJ】1055: [HAOI2008]玩具取名(dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1055

    我竟然都没往dp这个方向想。。。。。百度了下看到标题是dp马上就会转移了QAQ。。。

    设d[i,j,k]表示i~j是否能转移成k。

    那么很显然。。

    d[i,j,k]=d[i,k,x]&&d[k+1,j,y]&&a[k,x,y],a[k,x,y]表示k能转移到xy。

    然后我数组小了re。。(我都开了202啦。。。。。。。。。。。

    然后没有判误解wa了。。。。。。太sb。。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <set>
    #include <map>
    using namespace std;
    typedef long long ll;
    #define rep(i, n) for(int i=0; i<(n); ++i)
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    #define for2(i,a,n) for(int i=(a);i<(n);++i)
    #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    #define for4(i,a,n) for(int i=(a);i>(n);--i)
    #define CC(i,a) memset(i,a,sizeof(i))
    #define read(a) a=getint()
    #define print(a) printf("%d", a)
    #define dbg(x) cout << (#x) << " = " << (x) << endl
    #define error(x) (!(x)?puts("error"):0)
    #define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
    inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
    
    const int N=305;
    bool d[N][N][4], a[4][4][4];
    int n;
    char s[N];
    int f[N];
    int getid(char c) { if(c=='W') return 0; if(c=='I') return 1; if(c=='N') return 2; return 3; }
    void rdin(int c, int w) { rep(i, c) { scanf("%s", s); int x=getid(s[0]), y=getid(s[1]); a[w][x][y]=1; } }
    int main() {
    	rep(i, 4) read(f[i]);
    	rep(i, 4) rdin(f[i], i);
    	scanf("%s", s+1);
    	n=strlen(s+1);
    	for1(i, 1, n) f[i]=getid(s[i]);
    	for1(i, 1, n-1) rep(k, 4) { int x=f[i], y=f[i+1]; if(a[k][x][y]) d[i][i+1][k]=1; }
    	for1(i, 1, n) d[i][i][f[i]]=1;
    	for1(l, 3, n) for1(i, 1, n) {
    		int j=i+l-1;
    		rep(k, 4) rep(x, 4) rep(y, 4) if(a[k][x][y]) {
    			for1(kk, i, j-1) if(d[i][kk][x] && d[kk+1][j][y]) d[i][j][k]=1;
    		}
    	}
    	//for1(i, 1, n) for1(j, i+1, n) rep(k, 4) printf("%d %d %d:%d
    ", i, j, k, d[i][j][k]);
    	int flag=d[1][n][0]||d[1][n][1]||d[1][n][2]||d[1][n][3];
    	if(!flag) { puts("The name is wrong!"); return 0; }
    	if(d[1][n][0]) putchar('W');
    	if(d[1][n][1]) putchar('I');
    	if(d[1][n][2]) putchar('N');
    	if(d[1][n][3]) putchar('G');
    	return 0;
    }
    

      


    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


    Source

     
  • 相关阅读:
    如何恢复包含损坏记录的物理文件
    启动日志
    如何在各种环境中处理多成员的物理文件
    如何找出物理文件中损坏的记录
    如何重新找回物理文件中已经被删除的记录
    folder的操作
    如何将AS/400英文界面改为中文界面?
    如何从OS/400里直接发送电子邮件到Internet
    如何在AS/400上发送带有颜色的MESSAGE
    关于命令RGZPFM
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4163934.html
Copyright © 2011-2022 走看看