C++ 最长单调子序列

最长单调子序列 代码框架 代码见下

cpp 复制代码
#include<iostream>
using namespace std;

#define maxn 5010
int a[maxn];
// 模版为最长递增子序列
// 如果要改成单调不降呢 a[i] <= g[mid] 改为 a[i] < g[mid]
int getLTS(int n, int a[], int dp[]) {
	int g[maxn], gSize = 0;
	for (int i = 0; i < n; ++i) {
		int l = -1, r = gSize;
		while (l + 1 < r) {
			int mid = (l + r) >> 1;
			if (a[i] <= g[mid]) {
				r = mid;
			}
			else {
				l = mid;
			}
		}
		if (r == gSize) {
			g[gSize++] = a[i];
		}
		else {
			g[r] = a[i];
		}
		dp[i] = gSize;
	}
	return gSize;
}

int dp[maxn];

int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; ++i) {
		cin >> a[i];
	}
	cout << getLTS(n, a, dp) << endl;
	return 0;
}

代码练习 1 对应蓝桥云课 蓝桥骑士 代码见下

cpp 复制代码
#include<iostream>
using namespace std;

#define maxn 300010
int a[maxn];
// 模版为最长递增子序列
// 如果要改成单调不降呢 a[i] <= g[mid] 改为 a[i] < g[mid]
int getLTS(int n, int a[], int dp[]) {
	int g[maxn], gSize = 0;
	for (int i = 0; i < n; ++i) {
		int l = -1, r = gSize;
		while (l + 1 < r) {
			int mid = (l + r) >> 1;
			if (a[i] <= g[mid]) {
				r = mid;
			}
			else {
				l = mid;
			}
		}
		if (r == gSize) {
			g[gSize++] = a[i];
		}
		else {
			g[r] = a[i];
		}
		dp[i] = gSize;
	}
	return gSize;
}

int dp[maxn];

int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; ++i) {
		cin >> a[i];
	}
	cout << getLTS(n, a, dp) << endl;
	return 0;
}

代码练习 2 对应蓝桥云课 合唱队形 代码见下

cpp 复制代码
#include<iostream>
using namespace std;

#define maxn 110
int a[maxn];
// 模版为最长递增子序列
// 如果要改成单调不降呢 a[i] <= g[mid] 改为 a[i] < g[mid]
int getLTS(int n, int a[], int dp[]) {
	int g[maxn], gSize = 0;
	for (int i = 0; i < n; ++i) {
		int l = -1, r = gSize;
		while (l + 1 < r) {
			int mid = (l + r) >> 1;
			if (a[i] <= g[mid]) {
				r = mid;
			}
			else {
				l = mid;
			}
		}
		if (r == gSize) {
			g[gSize++] = a[i];
		}
		else {
			g[r] = a[i];
		}
		dp[i] = gSize;
	}
	return gSize;
}

int dp[maxn];

void swap(int n, int a[]){
  for(int i=0; i<n/2; ++i){
    swap(a[i], a[n-1-i]);
  }
}

int dppre[maxn], dppost[maxn];

int main(){
  int n;
  cin >> n;
  for(int i=0; i<n; ++i){
    cin >> a[i];
  }
  getLTS(n, a, dppre);
  swap(n, a);
  getLTS(n, a, dppost);
  swap(n, dppost);
  int ans = 0;
  for(int i=0; i<n; ++i){
    ans = max(ans, dppre[i] + dppost[i] - 1);
  }
  cout << n - ans << endl;
  return 0;

}

代码 3 对应蓝桥云课 拍照 代码见下

cpp 复制代码
#include<iostream>
using namespace std;

#define maxn 110
int a[maxn];
// 模版为最长递增子序列
// 如果要改成单调不降呢 a[i] <= g[mid] 改为 a[i] < g[mid]
int getLTS(int n, int a[], int dp[]) {
	int g[maxn], gSize = 0;
	for (int i = 0; i < n; ++i) {
		int l = -1, r = gSize;
		while (l + 1 < r) {
			int mid = (l + r) >> 1;
			if (a[i] < g[mid]) {
				r = mid;
			}
			else {
				l = mid;
			}
		}
		if (r == gSize) {
			g[gSize++] = a[i];
		}
		else {
			g[r] = a[i];
		}
		dp[i] = gSize;
	}
	return gSize;
}

int dp[maxn];

void swap(int n, int a[]){
  for(int i=0; i<n/2; ++i){
    swap(a[i], a[n-1-i]);
  }
}

int dppre[maxn], dppost[maxn];

int main(){
  int n;
  cin >> n;
  for(int i=0; i<n; ++i){
    cin >> a[i];
  }
  getLTS(n, a, dppre);
  swap(n, a);
  getLTS(n, a, dppost);
  swap(n, dppost);
  int ans = 0;
  for(int i=0; i<n; ++i){
    ans = max(ans, dppre[i] + dppost[i] - 1);
  }
  cout << n - ans << endl;
  return 0;

}
相关推荐
光羽隹衡16 小时前
机械学习逻辑回归——银行贷款案例
算法·机器学习·逻辑回归
Code Warrior17 小时前
【C++】智能指针的使用及其原理
开发语言·c++
能源系统预测和优化研究17 小时前
创新点解读:基于非线性二次分解的Ridge-RF-XGBoost时间序列预测(附代码实现)
人工智能·深度学习·算法
执笔论英雄17 小时前
【RL】ROLL下载模型流程
人工智能·算法·机器学习
yaoh.wang17 小时前
力扣(LeetCode) 100: 相同的树 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·跳槽
SadSunset17 小时前
力扣题目142. 环形链表 II的解法分享,附图解
算法·leetcode·链表
月光在发光17 小时前
多态(虚函数核心作用原理)--C++学习(0)
c++·学习
Sunsets_Red17 小时前
2025 FZYZ夏令营游记
java·c语言·c++·python·算法·c#
自由生长202418 小时前
从流式系统中思考-C++生态和Java生态的区别
java·c++
iAkuya18 小时前
(leetcode)力扣100 19螺旋矩阵(方向数组/边界把控)
算法·leetcode·矩阵