CSU 1120 病毒

时间:2022-04-28 04:42:41

最长公共上升子序列(LCIS)

裸的算法题。

动态规划:

  两组数组a[n]、b[m]。

  f[i][i]表示以a[i]、b[j]结尾的两个数组的LCIS。

  转移方程:

    a[i]!=b[j] : f[i][j]=f[i-1][j];

    a[i]==b[j] : f[i][j]=max (f[i-1][k]) + 1;(1<=k<j&&b[j]>b[k] )

  max (f[i-1][k])可以在访问f[i][k]的时候维护更新一个max变量来得到,这样就是O(n*m)的时间复杂度。

ps:找这个算法的时候看到某队省赛的时候不会,同病相怜哈,还好我们只是训练赛不会。灭哈哈哈~

 #include <iostream>
#include <cstring>
#include <cstdio>
using namespace std; int f[][];
int main (){//cout<<"error"<<endl;
int n1,n2;
int a[],b[];
int max;
int t;
cin>>t;
while (t--){
cin>>n1;
for (int i=;i<=n1;i++)
cin>>a[i];
cin>>n2;
for (int i=;i<=n2;i++)
cin>>b[i];
memset (f,,sizeof f);
for (int i=;i<=n1;i++){
max=;
for (int j=;j<=n2;j++){
f[i][j]=f[i-][j];
if (a[i]>b[j]&&f[i-][j]>max)
max=f[i-][j];
if (a[i]==b[j])
f[i][j]=max+;
}
}
int ans=;
for (int i=;i<=n2;i++)
if (f[n1][i]>ans)
ans=f[n1][i];//cout<<ans<<" ";
cout<<ans<<endl;
}
return ;
}