最长公共子序列
\(\mathcal{Description}\)
对于一个长度为\(A\)的正整数序列\(B\),定义其一个长度为\(C\left(0 < C \leq A\right)\)的非空子
序列为一个长度为\(C\)的下标序列\(P_{1 ... C}\),满足\(1 \leq P_1 < P_2 < ⋯ < P_C \leq A\)。
子序列本身就是按照顺序把对应的元素拿出来\(:B_{P_1},B_{P_2}, ... B_{P_C}\)
给定一个长度为\(N\)的正整数序列\(S\)和一个长度为\(M\)的正整数序列\(T\),同时再给
定一个有\(K\)条边的有向图\(G\)。请你求出它们有多少个公共子序列,满足把子序列
拿出来之后,对于任意相邻两个元素\((a, b)\),满足在\(G\)中存在一条有向边\(< a, b >\)
这里子序列不同,定义为下标位置不同(即序列\(P\)不同)。
\(1 ≤ N, M ≤ 3000 ,0 ≤ K ≤ 10^6 ,∀1 ≤ i ≤ N, 1 ≤ S[i] ≤ 10^9, ∀1 ≤ i ≤ M, 1 ≤ T[i] ≤ 10^9, 1 ≤ s, t ≤ 10^9\)
\(\mathcal{Solution}\)
考虑和求最长公共子序列类似的dp方式,先固定一个公共子序列的末端为ai,然后枚举bj 找到bj时将前面允许的合法转移加上即可
考试时脑子抽了,打了个树状数组,枚举边,但是ai被固定只需用邻接表查看即可
\(\mathcal{Code}\)
/*******************************
Author:Morning_Glory
LANG:C++
Created Time:2019年10月09日 星期三 08时13分00秒
*******************************/
#include <cstdio>
#include <fstream>
#include <algorithm>
using namespace std;
const int maxn = 6005;
const int mod = 1000000007;
//{{{cin
struct IO{
template<typename T>
IO & operator>>(T&res){
res=0;
bool flag=false;
char ch;
while((ch=getchar())>'9'||ch<'0') flag|=ch=='-';
while(ch>='0'&&ch<='9') res=(res<<1)+(res<<3)+(ch^'0'),ch=getchar();
if (flag) res=~res+1;
return *this;
}
}cin;
//}}}
int n,m,k,tot,ans;
int a[maxn],b[maxn],c[maxn],f[maxn];
bool mp[maxn][maxn];
inline void add (int &x,int y){ x=(x+y)%mod;}
inline int lsh (int x) { return lower_bound(c+1,c+tot+1,x)-c; }
int main()
{
/*
* 考虑和求最长公共子序列类似的dp方式,先固定一个公共子序列的末端为ai,然后枚举bj 找到bj时将前面允许的合法转移加上即可
* 考试时脑子抽了,打了个树状数组,枚举边,但是ai被固定只需用邻接表查看即可
*/
cin>>n>>m>>k;
for (int i=1;i<=n;++i) cin>>a[i],c[++tot]=a[i];
for (int i=1;i<=m;++i) cin>>b[i],c[++tot]=b[i];
sort(c+1,c+tot+1);
tot=unique(c+1,c+tot+1)-c-1;
for (int i=1;i<=n;++i) a[i]=lsh(a[i]);
for (int i=1;i<=m;++i) b[i]=lsh(b[i]);
for (int i=1;i<=k;++i){
int u,v,a,b;
cin>>a>>b;
u=lsh(a),v=lsh(b);
if (u<=tot&&v<=tot&&c[u]==a&&c[v]==b) mp[u][v]=true;
}
for (int i=1;i<=n;++i){
int s=1;
for (int j=1;j<=m;++j){
int t=f[j];
if (a[i]==b[j]) add(f[j],s),add(ans,s);
if (mp[b[j]][a[i]]) add(s,t);
}
}
printf("%d\n",ans);
return 0;
}
如有哪里讲得不是很明白或是有错误,欢迎指正
如您喜欢的话不妨点个赞收藏一下吧