ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Common Subsequence Gym - 102307C 公共序列

2019-09-14 12:01:21  阅读:411  来源: 互联网

标签:字符 匹配 int Gym 抛弃 Subsequence dp 个字符 Common


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;
}

 

标签:字符,匹配,int,Gym,抛弃,Subsequence,dp,个字符,Common
来源: https://www.cnblogs.com/downrainsun/p/11518754.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有