【HankerRank】LCS Returns(巧妙LCS)

【HankerRank】LCS Returns(巧妙LCS)**

LCS Returns

Given two strings, and , find and print the total number of ways to insert a character at any position in string such that the length of the Longest Common Subsequence of characters in the two strings increases by one.

Input Format

The first line contains a single string denoting a .
The second line contains a single string denoting b.

Constraints

Scoring

1/le|a|,|b|/le5000
Strings a and b are alphanumeric (i.e., consisting of arabic digits and/or upper and lower case English letters).
The new character being inserted must also be alphanumeric (i.e., a digit or upper/lower case English letter).

Output Format

Print a single integer denoting the total number of ways to insert a character into string in such a way that the length of the longest common subsequence of a and b increases by one.

Sample Input

aa
baaa

Sample Output

4

Explanation

The longest common subsequence shared by a="aa" and b="baaa" is aa, which has a length of 2 . There are two ways that the length of the longest common subsequence can be increased to by adding a single character to a:

There are 3 different positions in string where we could insert an additional a to create longest common subsequence aaa (i.e., at the beginning, middle, and end of the string).
We can insert a b at the beginning of the string for a new longest common subsequence of baa.
As we have 3+1=4 ways to insert an alphanumeric character into a and increase the length of the longest common subsequence by one, we print 4 on a new line.

题目大意:
a,b两个串。
可以求得两串的最长公共子序列。
问在a中加一个字符,有多少种加法能让a和b的最长公共子序列增长1

解法真的真的真的很6
脑洞要够大!
|
|
|
给点小提示 O(3NM) 的复杂度
|
|
|
|
在给点小提示 能变成 O(2NM+52N)
|
|
|
|
|
恩……能想到差不多该想到了
|
|
|
|
|
从左从右各跑一遍LCS
分别存下来。
|
|
|
然后可以 O(NM) 的枚举插入字符。
然后判断左边+右边最长上升子序列是否为a,b最长上升子序列,为的话,按该方法插入满足题意。遍历完即可求出答案。

优化的话把b中每个字符出现的位置顺序存储下来。

枚举a中每个位置插入’0’~’9’ ‘a’~’z’ ‘A’~’Z’然后遍历对应字符在b中的每个位置,如上判断即可

代码如下:

#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <list>
#include <algorithm>
#include <map>
#include <set>
#define LL long long
#define Pr pair<int,int>
#define fread(ch) freopen(ch,"r",stdin)
#define fwrite(ch) freopen(ch,"w",stdout)

using namespace std;
const int INF = 0x3f3f3f3f;
const int msz = 10000;
const int mod = 1e9+7;
const double eps = 1e-8;

char a[5555];
char b[5555];
int dp[2][5555][5555];
vector <int> pos[62];
int tp = 62;

int got(char ch)
{
    if('a' <= ch && ch <= 'z') return ch-'a';
    if('A' <= ch && ch <= 'Z') return ch-'A'+26;
    return ch-'0'+52;
}

int main()
{
    //fread("");
    //fwrite("");

    scanf("%s%s",a+1,b+1);
    int n,m;
    n = strlen(a+1);
    m = strlen(b+1);

    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
            dp[0][i][j] = max(dp[0][i-1][j],max(dp[0][i][j-1],dp[0][i-1][j-1]+(a[i]==b[j])));


    for(int i = n; i >= 1; --i)
        for(int j = m; j >= 1; --j)
            dp[1][i][j] = max(dp[1][i+1][j],max(dp[1][i][j+1],dp[1][i+1][j+1]+(a[i]==b[j])));


    for(int i = 1; i <= m; ++i)
        pos[got(b[i])].push_back(i);

    int ans = 0;
    int id;
    for(int i = 1; i <= n+1; ++i)
    {
        for(int j = 0; j < tp; ++j)
        {
            for(int k = 0; k < pos[j].size(); ++k)
            {
                id = pos[j][k];
                if(dp[0][i-1][id-1]+dp[1][i][id+1] == dp[0][n][m]) 
                {
                    ans++;
                    break;
                }
            }
        }
    }

    printf("%d\n",ans);

    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值