题解:P10954 LCIS

Solution P10954

Idea

我们设 dpi,jdp_{i,j}aa 序列考虑了前 ii 个数,以 bjb_j 结尾的最长 LCIS 长度。注意并不一定以 aia_i 结尾。

不设dpi,jdp_{i,j}aa 序列以 aia_ibjb_j 结尾的最长 LCIS 长度(要求必须以 aia_i 结尾)的原因是不保证 ai=bja_i=b_j;不设 dpi,jdp_{i,j}aa 序列考虑了前 ii 个数,bb 序列考虑了前 jj 个数的最长 LCIS 长度的原因是极难转移。

显然有:

  • aibja_i\neq b_j 时,dpi,j=dpi1,jdp_{i,j}=dp_{i-1,j}
  • ai=bja_i=b_j 时,dpi,j=max{dpi1,k}+1dp_{i,j}=\max\{dp_{i-1,k}\}+1,其中 k<jk<j

这样的复杂度是 O(n3)\operatorname{O}(n^3) 的,可以通过 CF10D。

然后不难发现 max{dpi1,k}\max\{dp_{i-1,k}\} 是一段前缀,可以直接预处理优化。

这样就省去了枚举 kk 的步骤,复杂度减为 O(n2)\operatorname{O}(n^2)

Code

#include<bits/stdc++.h>
using namespace std;
const int N=3005;
int n;
long long a[N],b[N],dp[N][N],ans,maxx;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
	for(int i=1;i<=n;i++)scanf("%lld",&b[i]);
	for(int i=1;i<=n;i++){
		maxx=0;
		for(int j=1;j<=n;j++){
			if(a[i]!=b[j])dp[i][j]=dp[i-1][j];
			else dp[i][j]=maxx+1;
			if(a[i]>b[j])maxx=max(maxx,dp[i-1][j]);//先计算后处理,因为 k<j
			ans=max(ans,dp[i][j]);
		}
	}
	printf("%lld",ans);
}
posted @   Weslie_qwq  阅读(2)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示