链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1264

思路: n大小为20000*5,而一般的dp求最长公共子序列复杂度是 n*n的,所以我们必须优化。

题目说了一个数会出现5次,那么我们可以预处理得到 第一个序列a[]每个数字分别在哪些位置,

因为求LCS的状态转移方程中当 s1[i-1] == s2[j-1]时,dp[i][j] = dp[i-1][j-1] + 1;只有当两个点相同时

值才会+1,我们可以对第二个序列b[]遍历一遍,对于b[i]我们可以找到它在a[]上的5个位置,这5个

位置的dp[pos]都可以被更新,状态转移方程为: dp[pos] = max(p[1] - p[pos-1]) + 1, 对于dp[1] - dp[pos],

这段区间的最大值,我们直接用树状数组维护就好了,时间复杂度为 O(n*logn)

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long const int M = 2e5+;
int a[M][],c[M],dp[M],n; void update(int x,int p){
while(x <= n*){
c[x] = max(c[x],p);
x += (x&-x);
}
} int getsum(int x){
int ans = ;
while(x){
ans = max(ans,c[x]);
x -= (x&-x);
}
return ans;
} int main()
{
int x;
cin>>n;
for(int i = ;i <= n*;i ++){
cin>>x;
a[x][++a[x][]] = i;
}
for(int i = ;i <= n*;i ++){
cin>>x;
for(int j = ;j >= ;j --){
int num = getsum(a[x][j]-)+;
if(num > dp[a[x][j]]) dp[a[x][j]] = num,update(a[x][j],num);
}
}
int ans = ;
for(int i = ;i <= n*;i ++){
ans = max(dp[i],ans);
}
cout<<ans<<endl;
return ;
}

最新文章

  1. C++ std::set
  2. Html5 Geolocation获取地理位置信息
  3. 将Excel数据导入Oracle中
  4. mvc5 @RenderSection(&quot;scripts&quot;, required: false) 什么意思
  5. Codeforces Round #325 (Div. 2) C. Gennady the Dentist 暴力
  6. Qt基于FFmpeg播放本地 H.264(H264)文件(灿哥哥的博客)
  7. HTML 5 学习 (1)
  8. 分享一个自用的 Inno Setup 软件打包脚本
  9. Linux学习记录--匿名沟通渠道
  10. Part 7:自定义admin站点--Django从入门到精通系列教程
  11. C# this关键字的四种用法
  12. [LeetCode] 12,13 整数和罗马数互转
  13. StringBuilder String string.Concat 字符串拼接速度再议
  14. 赚钱的小生意,VC对你没兴趣
  15. How to Redirect in ASPNET Web API
  16. Border属性的各种变化
  17. keras LSTM中间的dropout
  18. NSPredicate 的使用(持续更新)
  19. (转)&lt;Unity3D&gt;Unity3D在android下调试
  20. 使用nomad &amp;&amp; consul &amp;&amp; fabio 创建简单的微服务系统

热门文章

  1. 华为MAC Flapping , MAC的漂移
  2. codeforces#552 D. Vanya and Triangles(几何)
  3. PS调出甜美艺术外景女生照片
  4. MySQL 批量修改某一列的值为另外一个字段的值
  5. 爬虫——selenium基础
  6. Use the Microsoft Symbol for VS and Windbg
  7. C#中闭包的陷阱
  8. vue 中的slot属性(插槽)的使用
  9. 如何使用命令从linux服务器下载文件到windows
  10. Python自动化测试之selenium从入门到精通