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

    题意: 给定两个字符串,让求最少的变化次数从第一个串变到第二个串

    思路: 区间dp, 直接考虑两个串的话太困难,就只考虑第二个串,求从空白串变到第二个串的最小次数,dp[i][j] 表示i->j这个区间上的最优解,那么dp[i][j] = min(dp[i + 1][j], dp[i + 1][k] + dp[k + 1][j]),这个状态转移方程中是枚举k的位置,前提是第二个串的第i个字符必须和第k个字符相等,因为这样才是求的最优的,不然的话,就没必要刷到k这个位置了。到最后在枚举每个位置,看第一个串是否与第二个串的对应位置相等,找出最优解。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 110;
    int dp[maxn][maxn], ans[maxn];
    char a[maxn], b[maxn];
    int main()
    {
        while (~scanf("%s %s", a + 1, b + 1))
        {
            int len = strlen(a + 1);
            memset(dp, 0, sizeof(dp));
            for (int i = len; i >= 1; i--)
            {
                for (int j = i; j <= len; j++)
                {
                    dp[i][j] = dp[i + 1][j] + 1;
                    for (int k = i + 1; k <= j; k++)
                        if (b[i] == b[k])
                            dp[i][j] = min(dp[i][j], dp[i + 1][k] + dp[k + 1][j]);
                }
            }
            for (int i = 1; i <= len; i++)
                ans[i] = dp[1][i];
            for (int i = 1; i <= len; i++)
            {
                if (a[i] == b[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]);
                }
            }
            printf("%d
    ", ans[len]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Spring Boot JDBC 使用教程
    Spring Boot FreeMarker 使用教程
    椭圆曲线ECC ECDH原理&& javacard实现
    java中的强制类型转换:int和byte
    JUnit学习
    java异常处理
    Maven使用
    哈希表问题
    计数排序
    链表Linked List
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4773085.html
Copyright © 2011-2022 走看看