码迷,mamicode.com
首页 > 其他好文 > 详细

HDU3109: Worms(字符串变换类 DP)

时间:2019-06-07 11:02:40      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:include   ons   一个   fine   pac   std   规则   namespace   最小   

pro:开始有一个字母虫,然后字母虫在每一天可以选择自己身上的部分字母变换,变换规则形如A->BC。 现状给定最终字母虫的字符串,求最少用了多少天。

如有规则A->BC,B->AC,C->AB;则ACAB可以见过三天(A-BC-ACC-ACAC)或者两天(A-BC-ACAB)得来。 规则不超过80,字符串长度不超过50;

sol:dp[i][j][p]表示,最开始只有字母p,变换到[i,j]区间的最小天数。

         显然初始:dp[i][i][x]=c[i]==x?0:inf;

         其他:       dp[i][j][x]=min(dp[i][k][p],dp[k+1][j][q]+1);  当且当存在规则x->pq;

经验:在倒推比较难的情况下,我们表示的状态可以是最初状态。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=52;
char c[maxn],s[maxn*2][5];
int dp[maxn][maxn][maxn];
vector<int>A[20],B[20];
int main()
{
    int N,L;
    while(~scanf("%d",&N)){
        if(!N) break;
        rep(i,0,19) A[i].clear(),B[i].clear();
        rep(i,1,N){
             scanf("%s",s[i]);
             A[s[i][0]-A].push_back(s[i][1]-A);
             B[s[i][0]-A].push_back(s[i][2]-A);
        }
        scanf("%s",c+1); L=strlen(c+1);
        rep(i,1,L) rep(j,i,L) rep(k,0,19) dp[i][j][k]=L+1;
        rep(i,1,L) dp[i][i][c[i]-A]=0;
        rep(i,1,L) {
            rep(l,1,L-i){
                int r=l+i;
                rep(p,0,19){
                    rep(k,l,r-1){
                        for(int t=0;t<A[p].size();t++){
                            dp[l][r][p]=min(dp[l][r][p],max(dp[l][k][A[p][t]],dp[k+1][r][B[p][t]])+1);
                        }
                    }
                }
            }
        }
        int ans=L+1;
        rep(i,0,19) if(dp[1][L][i]!=-1) ans=min(ans,dp[1][L][i]);
        if(ans==L+1) ans=-1;
        printf("%d\n",ans);
    }
    return 0;
}

 

HDU3109: Worms(字符串变换类 DP)

标签:include   ons   一个   fine   pac   std   规则   namespace   最小   

原文地址:https://www.cnblogs.com/hua-dong/p/10987633.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!