HDU - 2476 String painter

来源:互联网 发布:淘宝客推广找不到宝贝 编辑:程序博客网 时间:2024/06/05 12:02

题意:给定两个长度相等,只有小写字母组成的字符串s和t,每步可以把s的一个连续的子串“刷”成同一个字母,问至少需要多少步才能把s变成t


思路:首先预处理,假设s串与t串没有相同的字母,那么用dp[i][j]表示从i刷到j与t相同的最小步数,那么初始化dp[i][j] = dp[i+1][j],唯一可以降低步数的可能是存在t[i] == t[k](i+1<=k<=j)那么显然可以先从i,j先刷成t[i],所以t[i]可以不用计入,然后再考虑dp[i+1][k]+dp[k+1][j],预处理完了之后便是区间DP了,设ans[i]表示前i位的最小值,那么枚举之前的位置求出最小值

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 105;char s1[MAXN],s2[MAXN];int dp[MAXN][MAXN];int ans[MAXN];int main(){    while (scanf("%s%s",s1,s2) != EOF){        int len = strlen(s1);        memset(dp,0,sizeof(dp));        for (int j = 0; j < len; j++){            for (int i = j; i >= 0; i--){                dp[i][j] = dp[i+1][j]+1;                for (int k = i+1; k <= j; k++)                    if (s2[i] == s2[k])                        dp[i][j] = min(dp[i][j],dp[i+1][k]+dp[k+1][j]);            }        }        cout << dp[0][len-1] << endl;        for (int i = 0; i < len; i++)            ans[i] = dp[0][i];        for (int i = 0; i < len; i++){            if (s1[i] == s2[i])                ans[i] = ans[i-1];            else {                for (int j = 0; j < i; j++)                    ans[i] = min(ans[i],ans[j]+dp[j+1][i]);           }        }        printf("%d\n",ans[len-1]);    }    return 0;}


0 0