[简单DP] 最长公共子序列/LCS

【模板】最长公共子序列

Portkey

LCS板题
考虑维护 f [ i ] [ j ] f[i][j] f[i][j]表示第一个数列第i位前和第二个数列第j位前的LCS

菜至极
只会 n 2 n^2 n2

考虑转化
这是个排列,就可以搞事情
把一个数列的数变成下标,相应的替换另一个数列里的数
这样不会改变两个数列LCS的本质
转化后发现只需要求另一个数列的LIS(最长上升子序列)了

LIS当然用单调队列优化
优秀✌️

#include 
using namespace std;
#define in Read()
int in
{
	int i = 0, f = 1;
	char ch = 0;
	while (!isdigit(ch) && ch != '-')
		ch = getchar();
	if (ch == '-')
		ch = getchar(), f = -1;
	while (isdigit(ch))
		i = (i << 1) + (i << 3) + ch - 48, ch = getchar();
	return i * f;
}

const int N = 1e5 + 5;
int n, a[N], b[N], q[N], len = 1;

int main()
{
	n = in;
	for (int i = 1; i <= n; ++i)
		a[in] = i;
	for (int j = 1; j <= n; ++j)
		b[j] = a[in];
	q[1] = b[1];
	for (int i = 1; i <= n; ++i)
	{
		if (b[i] > q[len])
		{
			q[++len] = b[i];
			continue;
		}
		int pos = lower_bound(q + 1, q + len + 1, b[i]) - q;
		q[pos] = min(q[pos], b[i]);
	}
	printf("%d\n", len);
	return 0;
}

你可能感兴趣的:(#,简单DP)