zoukankan      html  css  js  c++  java
  • Common Subsequence Gym

    2019 ICPC Universidad Nacional de Colombia Programming Contest C D J

     

    C. Common Subsequence

    题意:给出长度为n两个串,求两个串的最长公共子序列len,如果len>=0.99*n,两个串就是亲兄弟否则不是。

    解法:朴素的求LCS的时间复杂度是O(nm),这题肯定超时。正解不容易想,要注意到0.99这个特点,我们从这个特点下手也就是说最多只能抛弃0.01*n=1000个字符,

    那么我们设dp[i][j]为A串前i+dp[i][j]个字符抛弃掉i个字符,B串前j+dp[i][j]个字符抛弃掉j个字符获得的LCS长度为dp[i][j]。

    那么对于此时枚举到的dp[i][j],i+dp[i][j]就是A串已经完成匹配的字符,j+dp[i][j]就是B串完成匹配的字符,换句话说就是AB串接下来开始的位置已经确定了,接下来我们继续从下一个字符开始匹配。

    dp[i][j]匹配完之后,A[i+dp[i][j]+1]和B[j+dp[i][j]+1]不相等,那么只能有两种选择抛弃A[i+dp[i][j]+1]或者抛弃B[j+dp[i][j]+1]。所以用dp[i][j]去更新这两个值

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    char A[N],B[N];
    int n,m,ans,dp[1010][1010];
    
    int main()
    {
        scanf("%s%s",A+1,B+1);
        n=strlen(A+1);
        m=min(1000,n);
        for (int i=0;i<=m;i++)
            for (int j=0;j<=m;j++) {
                while (A[i+dp[i][j]+1]==B[j+dp[i][j]+1] && i+dp[i][j]+1<=n && j+dp[i][j]+1<=n) dp[i][j]++;
                dp[i+1][j]=max(dp[i+1][j],dp[i][j]);
                dp[i][j+1]=max(dp[i][j+1],dp[i][j]);
                ans=max(ans,dp[i][j]);
            }
        if (100*ans>=99*n) puts("Long lost brothers D:"); else puts("Not brothers :(");
        return 0;
    }
  • 相关阅读:
    C语言文法
    实验一
    词法分析
    py中文词频统计
    py字符串练习
    py画了个国旗
    熟悉常用的Linux操作
    大数据概述
    实验三、 递归下降分析程序实验
    简易c语言LL(1)文法
  • 原文地址:https://www.cnblogs.com/downrainsun/p/11518754.html
Copyright © 2011-2022 走看看