• 2016级算法第四次上机-F.AlvinZH的最“长”公共子序列


    940 AlvinZH的最“长”公共子序列

    思路

    DP,难题。

    (dp[i][j]) :记录A的前i个字符与B的前j个字符变成相同需要的最小操作数。

    初始化:dp[i][0] = i, dp[0][i] = i。分别代表i次删除or添加操作。

    三种操作得到dp[i][j],取其中最小值:

    • 替换:可能不需要替换,所以是dp[i-1][j-1]+Same(A[i-1],B[j-1]);
    • 删除:dp[i-1][j]+1;
    • 添加:dp[i][j-1]+1。

    千万不要纠结操作的序列是A还是B!

    其实这是《算法导论》上一个“编辑距离”问题,比较经典,有兴趣的同学可以看看书or百度看看。

    分析

    没法分析,DP岂是我等凡人能理解的,sad。

    稍微分析,时间复杂度O(n^2)。

    参考代码一

    //
    // Created by AlvinZH on 2017/10/16.
    // Copyright (c) AlvinZH. All rights reserved.
    //
    
    #include <cstdio>
    #include <cstring>
    
    char A[1005], B[1005];
    int dp[1005][1005];//记录A的前i个字符转换到B的前j个字符的最小操作数
    
    inline int Same(char a, char b) {
        if(a == b) return 0;
        else return 1;
    }
    inline int MIN(int a, int b, int c) {
        if(a > b) a = b;
        if(a > c) a = c;
        return a;
    }
    
    int main()
    {
        while(~scanf("%s %s", A, B))
        {
            int lenA = strlen(A);
            int lenB = strlen(B);
    
            for (int i = 0; i <= lenA; ++i)
                dp[i][0] = i;//i次删除操作
            for (int i = 0; i <= lenB; ++i)
                dp[0][i] = i;//i次添加操作
    
            for (int i = 1; i <= lenA; ++i) {
                for (int j = 1; j <= lenB; ++j) {
                    dp[i][j] = MIN(dp[i-1][j-1]+Same(A[i-1],B[j-1]), dp[i-1][j]+1, dp[i][j-1]+1);
                    //MIN(替换, 删除, 添加)
                }
            }
    
            printf("%d
    ", dp[lenA][lenB]);
        }
    }
    
  • 相关阅读:
    springboot实现redis的分布式锁
    剑指offer--二维数组中查找
    剑指offer--二维数组中查找
    对JDK动态代理的模拟实现
    Spring(4)AOP
    设计模式之单例模式(Java)
    【Java并发系列】--Java内存模型
    maven 解决jar包冲突及简单使用
    基于注解的SpringAOP源码解析(三)
    Java代码中可以优化性能的小细节
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/7978022.html
Copyright © 2020-2023  润新知