ch0501 LCIS

题目链接:https://ac.nowcoder.com/acm/contest/1041/B

题意:求两个序列的最长公共上升子序列

一开始写的状态是以Ai,Bj为结尾的LCIS的长度,但发现这样的转移方程写出来是O(N^4)的。实际的状态应该是f[i][j]表示考虑A1到Ai,B1到Bj,以Bj为结尾的LCIS的长度,那么有转移方程:

f[i][j]=f[i-1][j] (Ai!=Bj)

f[i][j]=max(f[i-1][k])+1 0<=k<=j-1且Bk<Bj (Ai=Bj)

可以在枚举j时用一个变量维护f[i-1][k]的最大值(而且要满足Bk<Bj=Ai),这样复杂度降为O(n^2)

#include<bits/stdc++.h>
using namespace std;

const int N=3000+10;
int a[N],b[N],f[N][N],n,i,j,x;

int main(){
	cin>>n;
	for (i=1;i<=n;i++) cin>>a[i];
	for (i=1;i<=n;i++) cin>>b[i];
	a[0]=b[0]=-1e9;
	for (i=1;i<=n;i++){
	  int x=0;
	  for (j=1;j<=n;j++){
	  	if (a[i]==b[j]) f[i][j]=max(f[i-1][j],x+1);
	  	else f[i][j]=f[i-1][j];
	  	if (b[j]<a[i]) x=max(x,f[i-1][j]);
	  } 
	}
	int ans=0;
	for (i=1;i<=n;i++) ans=max(ans,f[n][i]);
	cout<<ans<<endl;
	return 0;
}

  

原文地址:https://www.cnblogs.com/edmunds/p/13620933.html