区间DP
luogu 4290
明显的区间DP.
定义
dp[l][r][k]/*表示区间[l,r]能否凑成k(W,I,N,G)字符*/
mp['W']=1;mp['I']=2;mp['N']=3;mp['G']=4;
之后选择比较好写的记忆化搜索去完成
AC码
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int na[5],dp[210][210][4],mp[255],len; char change[5][20][210],toy[210],h[]={' ','W','I','N','G'}; bool dfs(int l,int r,int k) { if(l==r) return toy[l]==h[k];//len<=1,不能换了 int& res=dp[l][r][k]; if(~res) return res;//11,12行这样更快,不会T掉,可以看上面的记录 for(int i=1;i<=na[k];i++) for(int j=l;j<r;j++) if(dfs(l,j,mp[change[k][i][0]])&&dfs(j+1,r,mp[change[k][i][1]])) return res=1; return res=0; } int main() { memset(dp,-1,sizeof(dp)); for(int i=1;i<=4;i++) scanf("%d",&na[i]); for(int i=1;i<=4;i++) { for(int j=1;j<=na[i];j++) { scanf("%s",&change[i][j]); } } scanf("%s",toy+1); len=strlen(toy+1); bool flag=0; mp['W']=1;mp['I']=2;mp['N']=3;mp['G']=4; for(int i=1;i<=4;i++) if(dfs(1,len,i)) { flag=1; printf("%c",h[i]); } if(!flag) puts("The name is wrong!"); return 0; }
2019-09-19 22:22:05