这俩感觉都是最长上升/下降子序列的问题…用二分查找优化
当成一个模板背好了(
这道题是直接copy了拦截导弹的代码改了改
放到了麻烦的聚餐上用的(
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100010;
int dp[N];
int a[N];
int dp2[N];
int main() {
int n;
cin >> n;
//for (int i = 1; i <= n; i++)cin >> a[i];
int res = -1;
int res2 = 0;
dp[0] = 0x3f3f3f;
dp2[0] = -1;
for (int i = 1; i <= n; i++) {
cin >> a[i];
dp[i] = 0x3f3f3f;
dp2[i] = -1;
}
//for (int i = 1; i <= n; i++)cout << a[i] << " ";
int idx = 0;
for (int i = 1; i <= n; i++) {
if (a[i] <= dp[idx])dp[++idx] = a[i];//如果能拦截
else {//看看前面的能不能有 如果没有那就往后+
int l = 1, r = idx;
while (l < r) {
int mid = l + r >> 1;
if (a[i] > dp[mid])r = mid;
else l = mid + 1;
}
dp[l] = a[i];
}
}
res = max(res, idx);
idx = 0;
for (int i = 1; i <= n; i++) {
if (a[i] > dp2[idx])dp2[++idx] = a[i];
else {
int l = 1, r = idx;
while (l < r) {
int mid = l + r >> 1;
if (dp2[mid] >= a[i])r = mid;
else l = mid + 1;
}
dp2[l] = a[i];
}
}
res = max(res, idx);
cout << n-res;
return 0;
}