#动态规划,线性动态规划#codevs 2185 CH 5101 LCIS 最长公共上升子序列

题目

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


分析

首先,优化的方法

for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
    if (a[i]==b[j])
    for (int k=0;k<j;k++)
        if (b[k]<a[i])
        f[i][j]=max(f[i][j],f[i-1][k]+1);

但是 O ( n 3 ) O(n^3) O(n3)的算法对于 n ≤ 3000 n\leq 3000 n3000的数据是无法承受的,所以应该怎么优化呢?
冗余的地方就是不断地 k k k循环,所以可以考虑 k k k i i i是可以定下来的,所以 b [ k ] &lt; a [ i ] b[k]&lt;a[i] b[k]<a[i]是固定的,当 j j j增加时,k也会因此增加,所以只要判断 b [ j ] &lt; a [ i ] b[j]&lt;a[i] b[j]<a[i],已经可以满足的k就不会被遗漏
放上滚动的 O ( n 2 ) O(n^2) O(n2)算法

for (int i=1;i<=n;i++){
		int maxx=0;//表示包含i的上升子序列的最长长度
		for (int j=1;j<=n;j++)
		if (b[j]<a[i]) maxx=max(maxx,f[j]);//上升子序列
		 else if (b[j]==a[i]) f[j]=maxx+1;//公共子序列增加
	}

代码

#include <cstdio>
int n,a[3001],b[3001],f[3001];
int max(int a,int b){return (a<b)?b:a;}
int main(){
	scanf("%d",&n); int ans=0;
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	for (int i=1;i<=n;i++) scanf("%d",&b[i]);
	for (int i=1;i<=n;i++){
		int maxx=0;
		for (int j=1;j<=n;j++)
		if (b[j]<a[i]) maxx=max(maxx,f[j]);
		 else if (b[j]==a[i]) f[j]=maxx+1;
	}ans=0;
	for (int i=1;i<=n;i++) ans=max(ans,f[i]);
	return !printf("%d",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值