zoukankan      html  css  js  c++  java
  • 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]);
        }
    }
    
  • 相关阅读:
    jvm client模式和server模式
    TOMCAT开启APR模式
    Spring MVC 关于controller的字符编码问题
    彻底解决Spring MVC 中文乱码 问题
    js中字符串拼接html
    分布式文件系统之MooseFS----介绍
    CopyFile函數詳解
    Delphi 接口使用中,对象生命周期管理,如何释放需要注意的问题
    年度调查 看看 2016 年 Go 语言调查结果
    Sleep(0)的作用
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/7978022.html
Copyright © 2011-2022 走看看