14-高效求最长公共子序列(二维数组存不下)

摘要:
/*SeeLCSagain时间限制:1000ms|内存限制:65535KB难度:3描述ThereareA,Btwosequences,thenumberofelementsinthesequenceisn、m;Eachelementinthesequencearedifferentandlessthan100000.Calculatethelengthofthelongestcommonsubse

/* 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
*/
//题意是要求公共子序列的长度,并且保证输入串中每串数字中没有重复的数字;
//由于题目给的数据要求太大,故用一般的二维数组dp内存就超了,所以借鉴了一个大牛的技巧,将问题转化为求最长上
//升子序列。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int a[N];
int b[N];

int find(int l, int r, int k){
	while(l < r){
		int mid = (l + r) / 2;
		if(a[mid] == k){
			return mid;
		}
		else if(a[mid] > k){
			r = mid;
		} 
		else{
			l = mid + 1;
		}
	}
	return r;
}

int main(){
	std::ios::sync_with_stdio(false);
	int n, m;
	while(cin >> n >> m){
		memset(a, 0, sizeof(a));
		memset(b, 0, sizeof(b));
		int x;
		for(int i = 1; i <= n; i++){
			cin >> x;
			a[x] = i;     //将第一串数字,标记在a数组中,将对应位置存为对应数字出现的序号 
		}
		int ct = 0;
		for(int i = 1; i <= m; i++){
			cin >> x;
			if(a[x]){			//看该数字是否在第一串数字中出现 
				b[ct++] = a[x];  //将公共数字出现的序号存下来,所以后面最长上升子序列就是两串数字的公共子序列个数
			}
		}
		int t = 0;
		a[t] = b[0];
		for(int i = 1; i < ct; i++){
			if(b[i] > a[t]){
				a[++t] = b[i];
			}
			else{
//				int w = find(0, t, b[i]);
				int w = lower_bound(a, a + t, b[i]) - a; //注意lower_bound 的用法,lower_bound返回的是一个地址
				a[w] = b[i];
			}
		}
		cout << t + 1<< endl;
	}
	return 0;
} 

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int a[100005];
int b[100005];
int find(int *c, int low, int high, int x){
while(low < high){
int mid = (low + high) / 2;
if(x < c[mid]){
high = mid;
}
else{
low = mid + 1;
}
}
return low;
}
int main(){
int n, m;
while(~scanf("%d%d", &n, &m)){
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
int x = 0;
for(int i = 1; i <= n; i++){
scanf("%d", &x);
a[x] = i; //将第一串数字,标记在a数组中,将对应位置存为对应数字出现的序号
}
int y = 0, j = 0;
for(int i = 1; i <= m; i++){
scanf("%d", &y);
if(a[y]){ //看该数字是否在第一串数字中出现
b[j++] = a[y]; //将公共数字出现的序号存下来,所以后面最长上升子序列就是两串数字的公共子序列个数
}
}
//求b的上升子序列:
int len = 0, c[10005]={b[0]};
for(int i = 1; i < j; i++){
if(b[i] > c[len]){
c[++len] = b[i];
}
else{
int w = find(c, 0, len, b[i]);
c[w] = b[i];
}
}
printf("%d ", len + 1);
}
return 0;
}

免责声明:文章转载自《14-高效求最长公共子序列(二维数组存不下)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇glViewport()函数和glOrtho()函数的理解django的数据库ORM进阶操作下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

[转]对齐次坐标的理解

“齐次坐标表示是计算机图形学的重要手段之一,它既能够用来明确区分向量和点,同时也更易用于进行仿射(线性)几何变换。”——F.S. Hill, JR。 齐次坐标主要是应用在矩阵转换中,我们通常运算的坐标系是“笛卡尔坐标系”,我们已经习惯了笛卡尔坐标系的表述方式,一个点都有唯一对应的数据值来表示,比如原点我们就记做(0,0)点。而笛卡尔坐标系和齐次坐标系的根...

MATLAB

总原则:能用向量矩阵解决的就不用for循环。 1.匿名函数  @定义一个函数或变量,用括号里的字母作为变量名字。 标准格式是: fhandle=@(arglist)express (1)express是一个matlab变量表达式,比如:x+x.^2,sin(x)等(2)argilst是参数列表;(3)符号@是matlab创建函数句柄的操作符,表示创建由参数...

Matlab读取Excel的数据

matlab读取excel中的数据用的是xlsread()这个函数这句代码跟matlab菜单操作中的file中import再选择excel文件的效果是一样的手动导入的时候它会自动识别文件中有什么类型的数据,数字和字符串被分别读入到两个变量中。比如[A B] = xlsread('1.xmls'); A中存储了这个文件中的数字矩阵,B中存储了字符串矩阵,读取...

MATLAB绘图

Matlab绘图 强大的绘图功能是Matlab的特点之一,Matlab提供了一系列的绘图函数,用户不需要过多的考虑绘图的细节,只需要给出一些基本参数就能得到所需图形,这类函数称为高层绘图函数。此外,Matlab还提供了直接对图形句柄进行操作的低层绘图操作。这类操作将图形的每个图形元素(如坐标轴、曲线、文字等)看做一个独立的对象,系统给每个对象分配一个句柄,...

OptimalSolution(5)--数组和矩阵问题(1)简单

  一、转圈打印矩阵   题目:给定一个整型矩阵matrix,按照转圈的方式打印它。   要求:额外空间复杂度为O(1) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 打印结果为:1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10   思路:矩阵分圈处理问题。用...

多分类问题中混淆矩阵(Confusion Matrix)的Matlab画法 | 丕子

在多分类问题中,有一种很实用的分类问题结果统计图。比如说多类别文类问题,那么每一个类别分到其他类别都有一些数据,但是分到自己类别的毕竟多,这样计算百分比之后就形成了一个矩阵,如果分类正确率高的话,那么对角线上的元素的值,也就是自己到自己的那一部分,value就大。我最近也在做多分类问题,要画这样的图,但是发现确实很少有代码,自己画的确实不好看,还牵扯到值的...