HDU 2476 String painter(区间dp)

来源:互联网 发布:张松献图 知乎 编辑:程序博客网 时间:2024/06/05 14:15
/*data: 2016/11/08writer: cn_swords题意:给你A,B两字符串,你一次操作可以将A一段全变为一个字符,问你最小次数把A变成B。题解:dp[l][r]代表区间(l,r)里,最小次数把这个区间的A变成B。当检查l位置A与B的时候,如果相同,dp[l][r] = dp[l+1][r];如果不同,初始化dp[l][r] = dp[l+1][r]+1,然后需要在区间(l+1,r)查找B[k]下是否有A[l]字符,dp[l][r] = dp[l+1][k]+dp[k+1][j]。但是这样是不正确的,因为(l,k)的区间改变会改变A串。正解: dp[l][r]代表区间(l,r)里,最小次数把这个区间的空串变成B。dp[l][r] = dp[l+1][r]+1; if(a[k] == a[l]) dp[l][r] = dp[l-1][k-1] + dp[k][r];( l+1 <= k <= r);处理完后,枚举区间(1,n),sum[i]代表处理前i个字符的最小处理次数。*/#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int INF = 0x3f3f3f3f;const int N = 105;char a[N],b[N];int sum[N];int dp[N][N];int main(){    while(~scanf("%s%s",a,b))    {        memset(dp,0,sizeof(dp));        int n = strlen(b);        for(int len = 0; len < n; len++)        {            for(int l = 0; l+len < n; l++)            {                if(len == 0)                {                    dp[l][l] = 1;                    continue;                }                int r = l+len;                dp[l][r] = dp[l+1][r]+(b[l] == b[l+1]?0:1);                for(int k = l+1; k <= r; k++)                {                    if(b[k] == b[l])                        dp[l][r] = min(dp[l][r],dp[l+1][k-1]+dp[k][r]);                }            }        }        //printf("%d\n",dp[0][n-1]);        //int ans = INF;        for(int i = 0; i < n; i++)        {            if(a[i] == b[i])                sum[i] = sum[i-1];            else                sum[i] = dp[0][i];            for(int j = 0; j < i; j++)                sum[i] = min(sum[i],sum[j]+dp[j+1][i]);        }        printf("%d\n",sum[n-1]);    }    return 0;}
0 0
原创粉丝点击