P4290 [HAOI2008]玩具取名
Posted lltyyc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4290 [HAOI2008]玩具取名相关的知识,希望对你有一定的参考价值。
$dp$
设 $f[i][j][k]$ 表示初始为 $k$ 时,能否得到 $[i,j]$ 这一段子串
设 $pd[i][j][k]$ 表示长度为二的字符串 $ij$ 能否由 $k$ 得到
然后枚举左右区间转移:有
$f[i][j][k]=[f[i][p][x]=1]\ and\ [f[p+1][j][y]=1]\ and\ [pd[x][y][k]=1]$
边界 $f[i][i][k]=[a[i]=k]$
然后直接记忆化搜索
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long ll; inline int read() int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) if(ch==‘-‘) f=-1; ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘) x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); return x*f; int n[7],a[207],m; int pd[7][7][7]; char s[207]; bool f[207][207][7],vis[207][207][7]; inline int F(char s) if(s==‘W‘) return 1; if(s==‘I‘) return 2; return s==‘N‘ ? 3 : 4; inline char DF(int x) if(x==1) return ‘W‘; if(x==2) return ‘I‘; return x==3 ? ‘N‘ : ‘G‘; bool dfs(int l,int r,int x) if(l==r&&a[l]==x) return 1; if(vis[l][r][x]) return f[l][r][x]; vis[l][r][x]=1; bool &T=f[l][r][x]; for(int i=l;i<r;i++) for(int j=1;j<=4;j++) for(int k=1;k<=4;k++) if(pd[j][k][x]&&dfs(l,i,j)&&dfs(i+1,r,k)) T=1; break; return T; int main() for(int i=1;i<=4;i++) n[i]=read(); for(int i=1;i<=4;i++) for(int j=1;j<=n[i];j++) scanf("%s",s); pd[F(s[0])][F(s[1])][i]=1; scanf("%s",s+1); m=strlen(s+1); for(int i=1;i<=m;i++) a[i]=F(s[i]); bool flag=0; for(int i=1;i<=4;i++) if(dfs(1,m,i)) printf("%c",DF(i)),flag=1; if(!flag) printf("The name is wrong!"); printf("\n"); return 0;
以上是关于P4290 [HAOI2008]玩具取名的主要内容,如果未能解决你的问题,请参考以下文章