题意
有趣的题目。
求最长公共子序列是否大于等于长度的
99
%
99\%
99%
正向的复杂度显然是
n
2
n^2
n2
做法是:
d
p
[
i
]
[
j
]
=
m
a
x
(
d
p
[
i
−
1
]
[
j
]
,
d
p
[
i
]
[
j
−
1
]
,
d
p
[
i
−
1
]
[
j
−
1
]
+
a
[
i
]
=
=
a
[
j
]
)
dp[i][j]=max(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]+a[i]==a[j])
dp[i][j]=max(dp[i−1][j],dp[i][j−1],dp[i−1][j−1]+a[i]==a[j])
但是不符合
1
e
5
1e5
1e5
换一种思路,删除的字母是比较少的,如果大于等于的话删除的一定不会超过
1000
1000
1000
我们设置
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]为分别删除
i
、
j
i、j
i、j个字母能够得到的最长长度。
首先当前已匹配过的长度为
i
+
d
p
[
i
]
[
j
]
i+dp[i][j]
i+dp[i][j]和
j
+
d
p
[
i
]
[
j
]
j+dp[i][j]
j+dp[i][j]判断后面一个位置相等,相等答案加,否则删除
A
A
A和
B
B
B中的一个
d
p
[
i
+
1
]
[
j
]
=
m
a
x
(
d
p
[
i
]
[
j
]
,
d
p
[
i
+
1
]
[
j
]
)
dp[i+1][j]=max(dp[i][j],dp[i+1][j])
dp[i+1][j]=max(dp[i][j],dp[i+1][j])
d
p
[
i
]
[
j
+
1
]
=
m
a
x
(
d
p
[
i
]
[
j
]
,
d
p
[
i
]
[
j
+
1
]
)
dp[i][j+1]=max(dp[i][j],dp[i][j+1])
dp[i][j+1]=max(dp[i][j],dp[i][j+1])
真不会。佩服了。
#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn = 500050;
typedef long long ll;
string A,B;
int dp[2005][2005];
int main(){
cin>>A>>B;
int n=min(int(A.size()),1000);
int m=min(int(B.size()),1000);
int ans=0;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
while(i+dp[i][j]+1<=n&&j+dp[i][j]+1<=m&&A[i+dp[i][j]]==B[j+dp[i][j]])dp[i][j]++;
dp[i+1][j]=max(dp[i][j],dp[i+1][j]);
dp[i][j+1]=max(dp[i][j],dp[i][j+1]);
ans=max(ans,dp[i][j]);
}
}
if(100*ans>=99*n)puts("Long lost brothers D:");
else puts("Not brothers :(");
}