程序设计Week10作业——B-LIS&LCS

题目描述

给出两个序列A、B,求A的LIS和AB的LCS的长度(LIS严格递增)

Input

第一行两个数n,m(1<=n<=5,000,1<=m<=5,000)
第二行n个数,表示序列A
第三行m个数,表示序列B

Output

输出一行数据ans1和ans2,分别代表序列A的LIS和序列AB的LCS的长度

解题思路

主要是LIS和LCS的求解方法:
LIS:线性dp,定义fi为以ai结尾的LIS的长度,f1=1,转移方程为:fi=max(fj)+1,其中0<j<i且aj<ai,最终结果:max(fi)(i=1,2……n);
LCS:定义f(i,j)为a1到ai和b1到bj的LCS长度,f(1,0)=f(0,1)=f(0,0)=0,转移方程为:ai==bj时,f(i,j)=f(i-1,j-1)+1,否则,f(i,j)=max(f(i-1,j),f(i,j-1)),最终结果:f(n,m)。

实现代码

#include<iostream>
#include<algorithm>
using namespace std;

int a[5010],b[5010];
int f1[5010],f2[5010][5010];

void LIS(int n)
{
	for(int i=2;i<=n;++i)
	{
		for(int j=1;j<i;++j)
		{
			if(a[j]<a[i])
				f1[i]=max(f1[i],f1[j]+1);
		}
	}
}

void LCS(int n,int m)
{
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=m;++j)
		{
			if(a[i]==b[j])
				f2[i][j]=f2[i-1][j-1]+1;
			else
				f2[i][j]=max(f2[i-1][j],f2[i][j-1]);
		}
	} 
} 

int main()
{
	int n,m,ans_lis=0;
	cin>>n>>m;
	for(int i=1;i<=n;++i)
		cin>>a[i];
	for(int i=1;i<=m;++i)
		cin>>b[i];
	for(int i=1;i<=n;++i)
		f1[i]=1;
	LIS(n);
	for(int i=1;i<=n;++i)
		ans_lis=ans_lis<f1[i]?f1[i]:ans_lis;
	f2[0][0]=0;
	f2[0][1]=0;
	f2[1][0]=0;
	LCS(n,m);
	cout<<ans_lis<<" "<<f2[n][m]<<endl;
	return 0;
} 

总结

这道题主要是对课上所讲的内容的一个练习,基本方法都已给出,照着写基本上没问题,这两种实现方法复杂度都是n^2,算是较为朴素且简单的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值