zoukankan      html  css  js  c++  java
  • HDU 2476 String painter 区间dp

    题目链接:点击打开链接

    给定2个长度相等的字符串a b

    每次能够把a串的随意一段变成一样的字母。

    问把a变成b最少须要几步。


    思路:

    1、dp[l][r] 表示把一个空字符串K 的[l,r] 变成 相应b[l,r]这段的最小花费。

    那么 dp[l][r] 就是 把 K[l] -> b[l], 然后再把 K[l+1, r] -> b[l+1, r]

    即: dp[l][r] = 1 + dp[l+1, r];

    可是若存在b[l] =  b[i] ( l+1 <= i <= r)

    那就能够先把空串 K[l, i] -> b[l], 然后再对 K[l+1, i] 操作。

    所以若 b[l] == b[i] 则 dp[l, r] = dp[l+1, i] + dp[i+1, r];

    若 b[l]!=b[i] ,那K[l] 变成b[l] 还是须要一步操作, : dp[l, r] = dp[l+1, i] + dp[i+1, r] +1;

    2、ANS[i] 表示把a[1,i] -> b[1,i]的最小花费。简单dp,不再赘述


    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    #include <cmath>
    using namespace std;
    const int inf = 1000000;
    const int N = 105;
    char s1[N], s2[N];
    int dp[N][N], len;//计算把空串的[i,j]段变成s2的[i,j]段须要的最少花费
    int dfs(int l, int r){
        if(l > r)return 0;
        if(dp[l][r] != -1) return dp[l][r];
        if(l == r) return dp[l][l] = 1;
        int ans = inf; //变第l个字符为 s2[l]
        for(int i = l+1; i <= r; i++)
        {
            int tmp = dfs(l+1, i) + dfs(i+1, r);
            if(s2[l] == s2[i])//变[l,i]字符为s2[l] 。这样单独变l 这步能够合并到变[l,i]这步里
                ans = min(ans, tmp);
            else
                ans = min(ans, tmp+1);
        }
        return dp[l][r] = ans;
    }
    void cal_dp(){
        memset(dp, -1, sizeof dp);
        for(int i = 1; i <= len; i++)
            for(int j = i; j <= len; j++)
                dfs(i, j);
    }
    
    int ANS[N];//把s1前i位变成s2的最小花费
    void find_ans(){
        ANS[1] = (s1[1] != s2[1]);
        for(int i = 2; i <= len; i++)
        {
            ANS[i] = dp[1][i];//空串变成s2的花费
            if(s1[i] == s2[i])
                ANS[i] = ANS[i-1];
            else
            {
                for(int j = 1; j < i; j++)
                    ANS[i] = min(ANS[i], ANS[j]+dp[j+1][i]);
            }
        }
    }
    int main(){
        while(~scanf("%s", s1+1)){
            scanf("%s", s2+1);
            len = strlen(s1+1);
            cal_dp();
            find_ans();
            printf("%d
    ", ANS[len]);
        }
        return 0;
    }
    


  • 相关阅读:
    Log4Net记录到MySql
    创建快照
    grep的用法(CentOS7)及有关正则表达式的使用
    samba
    mkdir
    raid0和raid5的 实验过程
    route
    source和sh执行脚本时的差异
    echo命令的简单用法和实例
    smbpasswd和pdbedit
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5147753.html
Copyright © 2011-2022 走看看