您的位置:首页 > 大数据 > 人工智能

HDU - 2476 String painter

2013-12-21 18:22 323 查看
题意:给定两个长度相等,只有小写字母组成的字符串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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: