NYOJ 760 See LCS again(基础dp+哈希表)(复习)

See LCS again

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述

There are A, B two sequences, the number of elements in the sequence is n、m;

Each element in the sequence are different and less than 100000.

Calculate the length of the longest common subsequence of A and B.

输入
The input has multicases.Each test case consists of three lines;
The first line consist two integers n, m (1 < = n, m < = 100000);
The second line with n integers, expressed sequence A;
The third line with m integers, expressed sequence B;
输出
For each set of test cases, output the length of the longest common subsequence of A and B, in a single line.
样例输入
5 4
1 2 6 5 4
1 3 5 4
样例输出
3

//注意理解题意啊,给我看红色区,本来打算利用一下数组下标的,但又觉得数字重复怎么办,哼,看了思路才恍然大悟

//其实就是利用数组下标,建立哈希函数对应关系,进而转化为最长上升子序列问题

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>

using namespace std;

int a[100000+10];
int dp[100000+10];
int len;
int binarysearch(int key)
{
	int left=1,right=len,mid;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(dp[mid]>key)
			right=mid-1;
		else
			left=mid+1;
	}
	return left;
}
int main()
{
	int n,m,x;
	while(~scanf("%d%d",&n,&m))
	{
		memset(dp,0,sizeof(dp));
		for(int i=1; i<=n; i++)
		{
			scanf("%d",&x);
			a[x]=i;
		}
		scanf("%d",&x);
		dp[1]=a[x];
		len=1;
		for(int i=2; i<=m; i++)
		{
			scanf("%d",&x);
			int t=binarysearch(a[x]);
			dp[t]=a[x];
			len=max(len,t);
		}
		printf("%d\n",len);
	}
	return 0; 
} //ac

//STL的算法

lower_bound(数组首地址,数组长度,查找元素val)函数是一个下确界,

[ first,last )前开后闭区间,从首元素开始查找,找到第一个大于等于val,

upper_bound(数组首地址,数组长度,查找元素val)函数是一个下确界,

[ first,last )前开后闭区间,从首元素开始查找,找到第一个大于val,

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>

using namespace std;

int g[100000+10];
int dp[100000+10];

int main()
{
	int n,m,x;
	while(~scanf("%d%d",&n,&m))
	{
		memset(dp,0,sizeof(dp));
		for(int i=1; i<=n; i++)
		{
			scanf("%d",&x);
			dp[x]=i;
		}
		int k=0;
		for(int i=1; i<=m; i++)
		{
			scanf("%d",&x);
			if(dp[x])
				g[k++]=dp[x];
		}
		int p=0;
		dp[p++]=g[0];
		for(int i=1; i<k; i++)
		{
			if(dp[p-1]<g[i])
				dp[p++]=g[i];
			else
			{
				x=lower_bound(dp,dp+p,g[i])-dp;
				dp[x]=g[i];
			}
		}
		printf("%d\n",p);
	}
	return 0; 
} //ac
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值