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;

}
相关推荐
vibecoding日记3 小时前
双非如何快速入职字节等大厂大模型?真实案例分析:推理优化和投机解码
算法·求职·大模型工程师
yszaygr21385 小时前
Verilog参数化游程编码RLE模块
算法
望易5 小时前
刚设计的大模型架构-双域耦合认知框架
算法·架构
复杂网络9 小时前
多个 Claude Code 与多个 Codex 协同工作:设计与实现方案
算法
apocelipes1 天前
常用编程语言和库的正则表达式性能对比
c语言·c++·python·性能优化·golang·开发工具和环境
HjhIron1 天前
面试常客:字符串算法从入门到进阶
算法·面试
吴佳浩1 天前
DeepSeek DSpark:Confidence-Scheduled Speculative Decoding 技术解析
人工智能·算法·deepseek
触底反弹1 天前
🧠 搞懂 Token,才算真正入门大模型——从分词原理到 Embedding 语义实战
javascript·人工智能·算法
vivo互联网技术1 天前
ICLR 2026 | 基于后验采样的图像恢复方法LearnIR:人脸去阴影、去雾
人工智能·算法·aigc
浮生望1 天前
JS字符串与回文算法:从包装类到双指针的面试进阶之路
javascript·算法