最长上升子序列模型 笔记

 首先附上模板:

#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
 
using namespace std;
 
typedef pair PII;
typedef long long ll;

const int N = 100010;

int n;
int a[N], q[N];

int main()
{
	IOS
	cin >> n;
	for(int i = 1; i <= n; i ++)
	{
		cin >> a[i];
	}
	int len = 0;
	q[0] = -2e9;
	for(int i = 1; i <= n; i ++)
	{
		int l = 0, r = len;
		while(l < r)
		{
			int mid = l + r + 1 >> 1;
			if(q[mid] < a[i])l = mid;
			else r = mid - 1;
		}
		len = max(len, r + 1);
		q[r + 1] = a[i];
	}
	cout << len;
	
	return 0;
}

友好城市

Palmia国有一条横贯东西的大河,河有笔直的南北两岸,岸上各有位置各不相同的N个城市。

北岸的每个城市有且仅有一个友好城市在南岸,而且不同城市的友好城市不相同。

每对友好城市都向政府申请在河上开辟一条直线航道连接两个城市,但是由于河上雾太大,政府决定避免任意两条航道交叉,以避免事故。

编程帮助政府做出一些批准和拒绝申请的决定,使得在保证任意两条航线不相交的情况下,被批准的申请尽量多。

输入格式

第1行,一个整数N,表示城市数。

第2行到第n+1行,每行两个整数,中间用1个空格隔开,分别表示南岸和北岸的一对友好城市的坐标。

输出格式

仅一行,输出一个整数,表示政府所能批准的最多申请数。

数据范围

1≤N≤5000,
0≤xi≤10000

输入样例:
7
22 4
2 6
10 3
15 12
9 8
17 17
4 2
输出样例:
4

最长上升子序列模型 笔记_第1张图片

可以把下面这行看成下标,上面对应的看成ai的值,每一种合法的解都必须满足a_{i+1}>a_i,如果a_{i+1}<a_i的话就会右交叉,以此转换为最长上升子序列模型

#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
 
using namespace std;
 
typedef pair PII;
typedef long long ll;
typedef pair PLI;

const int N = 5010;

int n;
int f[N];
int q[N], len;

int main()
{
	IOS
	cin >> n;
	vector A;
	for(int i = 0; i < n; i ++)
	{
		int x, y;
		cin >> x >> y;
		A.push_back({x, y});
	}
	sort(A.begin(), A.end());
	
	q[0] = -2e9;
	for(int i = 0; i < n; i ++)
	{
		int x = A[i].second, l = 0, r = len;
		while(l < r)
		{
			int mid = l + r + 1 >> 1;
			if(q[mid] < x)l = mid;
			else r = mid - 1;
		}
		len = max(len, r + 1);
		q[r + 1] = x;
	}
	cout << len;
	
	return 0;
}

你可能感兴趣的:(模板,dp,c++,动态规划)