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
Constraints
Scoring
1/le|a|,|b|/le5000
Strings
a
and
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
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
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
题目大意:
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;
}