bzoj1055 [HAOI2008]玩具取名 区间DP
问题描述
某人有一套玩具,并想法给玩具命名。首先他选择WING四个字母中的任意一个字母作为玩具的基本名字。然后
他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够扩充得很长。
现在,他想请你猜猜某一个很长的名字,最初可能是由哪几个字母变形过来的。
区间DP和记忆化
练习DP中。。代码几乎是照着题解写的。
题解:http://hzwer.com/5333.html 对代码进行了一些补充说明
#include<bits/stdc++.h> using namespace std; char s[4]={'W','I','N','G'}; char a[4][20][2],ch[220]; int f[210][210][4]; int q[250],t[5]; bool flag; bool dp(int l,int r,int k){ if(l==r){ return ch[l]==s[k]; } int &res=f[l][r][k];//为l到r的字母可不可以缩写成k if(res!=-1)return res; for(int i=1;i<=t[k];i++){ for(int j=l;j<=r-1;j++){ if(dp(l,j,q[a[k][i][0]])&&dp(j+1,r,q[a[k][i][1]]))//按区间进行比较 return res=1; } } return res=0; } int main(){ memset(f,-1,sizeof f); q['W']=0;q['I']=1;q['N']=2;q['G']=3; for(int i=0;i<4;i++)scanf("%d",&t[i]); for(int i=0;i<4;i++) for(int j=1;j<=t[i];j++)scanf("%s",a[i][j]); scanf("%s",ch+1); int n=strlen(ch+1); for(int i=0;i<4;i++) if(dp(1,n,i)){ flag=1;printf("%c",s[i]); } if(!flag)printf("The name is wrong!"); }