https://i.loli.net/2019/07/25/5d39b5315c60935716.jpg

2019年9月训练(贰)区间DP (luogu 4290)

区间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;

之后选择比较好写的记忆化搜索去完成

记录1  记录2  记录3

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

posted @ 2019-09-19 22:25  plzplz  阅读(113)  评论(0编辑  收藏  举报
https://i.loli.net/2019/07/25/5d39c1d4c249939054.jpg