字符刷子

来源:互联网 发布:前端页面如何优化 编辑:程序博客网 时间:2024/04/27 23:46

题目描述:略

题目分析:
关键字:DP,区间操作
我们从左边依次涂过去,若它的颜色与目标字符串不同,那么这个字符就一定要涂色,但此时的决策是把它向后涂多长(其实这里有个剪枝,只有后面的某个字符与现在要涂的颜色相同,涂到这里才是有意义的,读者自己领会)
当我们涂到后面的某个字符时,问题就分割成了一段都是相同颜色的,另一部分和原问题求的一样,最少涂多少次达到,发现了重复子问题,接下来就是DP。

可以定义dp[i][j][k]问满足【L,R】区间内都是k字符变成目标字符的最少次数。
发现两端问题其实求的内容差不多,修改一下,一并处理,当k为0时,字符为其本身。

代码如下:

#include<stdio.h>#include<string.h>#define M 105char A[M],B[M];int n,dp[M][M][30];int min(int a,int b){return a>b?b:a;}int dfs(int L,int R,int c){//[L,R]这个区间被刷上c这个颜色还需要的次数    if(L>R)return 0;    if(L==R){//c是A[L,R]的颜色         if(c==0)return A[L]!=B[L];        else return B[L]!=c;    }    int &t=dp[L][R][c];    if(t==-1){        t=1000000000;        if(c==0){            if(A[L]==B[L])t=dfs(L+1,R,c);            else{                for(int i=L;i<=R;i++)//从第一个字符向后刷到i                     if(B[i]==B[L])t=min(t,dfs(L,i,B[L])+1+dfs(i+1,R,c));            }        }else{            if(c==B[L])t=dfs(L+1,R,c);            else{                for(int i=L;i<=R;i++)//从第一个字符向后刷到i                     if(B[i]==B[L])t=min(t,dfs(L,i,B[L])+1+dfs(i+1,R,c));            }        }    }    return t;}int main(){    scanf("%s %s",A+1,B+1);    n=strlen(A+1);    for(int i=1;i<=n;i++){        A[i]=A[i]-'a'+1;        B[i]=B[i]-'a'+1;    }    memset(dp,-1,sizeof(dp));    printf("%d\n",dfs(1,n,0));    return 0;}
原创粉丝点击