BZOJ 1055 [HAOI2008]玩具取名

1055: [HAOI2008]玩具取名

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1119  Solved: 653
[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

Source

题解:区间DP嘛,L~R用a组可不可以,每次用字典来分割区间。

又因为没有解的情况WA了一发= =。。。。。。。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<stack>
 6 #include<queue>
 7 #include<cstring>
 8 #define PAU putchar(‘ ‘)
 9 #define ENT putchar(‘\n‘)
10 using namespace std;
11 const int maxn=200+10,inf=-1u>>1;
12 int id(char ch){
13     if(ch==‘W‘)return 0;
14     if(ch==‘I‘)return 1;
15     if(ch==‘N‘)return 2;
16     if(ch==‘G‘)return 3;
17     return -1;
18 }
19 void princ(int a){
20     if(!a)putchar(‘W‘);
21     else if(a==1)putchar(‘I‘);
22     else if(a==2)putchar(‘N‘);
23     else if(a==3)putchar(‘G‘);
24     return;
25 }
26 int t[4],tx[4][20][2],arr[maxn];int dp[4][maxn][maxn];
27 bool solve(int a,int L,int R){
28     int&res=dp[a][L][R];if(res!=-1)return res;
29     if(L==R)return (res=(arr[L]==a));
30     for(int i=L;i<R;i++){
31         for(int j=0;j<t[a];j++){
32             if(solve(tx[a][j][0],L,i)&&solve(tx[a][j][1],i+1,R))return (res=true);
33         }
34     }return (res=false);
35 }
36 inline int read(){
37     int x=0;bool sig=1;char ch=getchar();
38     for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)sig=0;
39     for(;isdigit(ch);ch=getchar())x=10*x+ch-‘0‘;
40     return sig?x:-x;
41 }
42 inline void write(int x){
43     if(x==0){putchar(‘0‘);return;}if(x<0)putchar(‘-‘),x=-x;
44     int len=0,buf[20];while(x)buf[len++]=x%10,x/=10;
45     for(int i=len-1;i>=0;i--)putchar(buf[i]+‘0‘);return;
46 }
47 char s[maxn];
48 int main(){
49     for(int i=0;i<4;i++)t[i]=read();
50     for(int i=0;i<4;i++){
51         for(int j=0;j<t[i];j++){
52             scanf("%s",s);tx[i][j][0]=id(s[0]);tx[i][j][1]=id(s[1]);
53         }
54     }
55     scanf("%s",s);
56     for(int i=0;s[i];i++)arr[i]=id(s[i]);int Len=strlen(s);
57     memset(dp,-1,sizeof(dp));bool flag=false;
58     for(int i=0;i<4;i++){
59         if(solve(i,0,Len-1))princ(i),flag=true;
60     }
61     if(!flag)puts("The name is wrong!");
62     return 0;
63 }
时间: 2024-10-21 00:44:00

BZOJ 1055 [HAOI2008]玩具取名的相关文章

bzoj 1055 [HAOI2008]玩具取名(区间DP)

1055: [HAOI2008]玩具取名 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1258  Solved: 729[Submit][Status][Discuss] Description 某 人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用 “WING”中任意两个字母代替,使得自己的名字能够扩充得很长.现在,他想请你猜猜某一个很长的名字,最初可能

[BZOJ 1055] [HAOI2008] 玩具取名 【记忆化搜索】

题目链接:BZOJ - 1055 题目分析 这种类似区间 DP 的记忆化搜索都是很相近的,比如字符串压缩和字符串扩展都差不多. 都是将现在 Solve 的区间分成子区间,再求解子区间. 这道题 Solve(l, r, x) 求能否将 [l, r] 的区间还原成 x ,那么就将它分成两段,看是否能左段变成 p , 右段变成 q. (x 能变成 pq) 代码 #include <iostream> #include <cstdio> #include <cstdlib> #

[BZOJ 1055][HAOI2008]玩具取名(DP)

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1055 分析: 比较难想的dp f[i][j][c]表示i..j能否压缩成字符c 那么怎么转移呢 如果存在i<=k<j,f[i][k][c1]=true且f[k+1][j][c2]=true且c1c2可以压缩成字符c(这个根据读入判断),那么f[i][j][c]就是true. 记忆化搜索比较好实现了.

BZOJ 1055 HAOI2008 玩具取名 动态规划

题目大意:给定一个由'W','I','N','G'构成的字符串,给定一些规则,这些规则可以将两个字符合成为一个,例如"II"可以合成为'W',"WW"可以合成为'I'或者'N' 求这个字符串可以最终合成为哪几种字符 看到这题我想到了广搜...其实没必要,动归完全可以解决 令f[i][j][k]为从i开始的j个字符是否可以合成为字符[k] 然后j从外层循环,剩下的全部预处理,怎么暴力怎么转移,我写了六层循环,有点吓人 #include<cstdio> #i

bzoj 1055 [HAOI2008]玩具取名 区间dp

题面 题目传送门 解法 直接区间dp即可 时间复杂度:\(O(16n^3)\) 代码 #include <bits/stdc++.h> #define N 210 using namespace std; struct Node { int x, y; } a[5][N]; int s[5], p[5][5][5]; bool f[N][N][5], vis[N][N][5]; int num(char ch) { if (ch == 'W') return 1; if (ch == 'I')

【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..

BZOJ1055: [HAOI2008]玩具取名

1055: [HAOI2008]玩具取名 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 820  Solved: 482[Submit][Status] Description 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够扩充得很长.现在,他想请你猜猜某一个很长的名字,最初可能是由哪几个字母变形过来的

bzoj1055: [HAOI2008]玩具取名(dp)

1055: [HAOI2008]玩具取名 题目:传送门 简要题意: 就是固定四个字母,给出这四个字母分别可以由哪两个字母组成,然后在给你一个字符串,要求把这个字符串还原成原始的四个字母的其中一个. 题解: 一开始看题有点瞎...想了想是一道超级大难题... 其实就是一个很简单的DP... 定义发f[i][j][s]:表示在字符串中i~j这个区间是否可以组合成为字符s 转移很容易就可以想出来:因为如果f[i][k][s1]==f[k+1][j][s2]==1(i<=k<=j) &&

[bzoj1055][HAOI2008]玩具取名_区间dp

玩具取名 bzoj-1055 HAOI-2008 题目大意:给你一个用W,I,N,G组成的字符串,给你一些这四个字符之间的变换规则,每一个变换规则都是由一个字符变成两个字符,问这个字符串是否可能是由一个单独的字符变成的. 注释:$1\le Len\le 200$,每种字符的变换规则<=16 想法:刚看见题以为又是什么单词接龙之类的题,然后看了一眼数据范围... ...还是不会. 查了题解,发现是一个挺不常见的bool区间dp 状态:dp[i][j][c]表示[i,j]这段区间是否能变成c字符,c