最长单调子序列 代码框架 代码见下
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;
}