裸的LIS(没学过。。
拿DP大力n2,直接超时
借此学一下LIS
————————————————————————————————————————————————————
DP数组: DP【i】代表长度为 i 的序列的结尾的 数字
思路有点贪心。
新的DP数组相当于一个贪心的序列。
从前往后扫描的过程中不断地把原序列的元素加入到DP数组里,对于每一个原序列的元素a【i】而言,应该插入的位置
是lower_bound(dp,dp+len,a[i]) 的位置(如果是不严格递增的话就是upper_bound(***) 的位置),插入的位置就是以a【i】
结尾的序列的最长的长度. 对于x和y,如果x < y且Stack[y] < Stack[x],用Stack[x]替换Stack[y],最长序列长度没有改
变但序列的''潜力''增大了。
最终dp数组的长度就是LIS长度
————————————————————————————————————————————————————
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[100000+4];
int b[100000+5];
int dp[100000];
int n;
int main()
{
int t;
cin >> n;
for(int i=0;i<n;i++) cin >> a[i];
int E = 0;
for(int i=n-1;i>=0;i--) b[E++] = a[i];
memset(dp, 0, sizeof(int)*n);
int len = 1;
dp[0] = a[0];
for (int i = 1; i < n; ++i)
{
int pos = upper_bound(dp, dp + len, a[i]) - dp;
dp[pos] = a[i];
// for(int j=0;j<len;j++) cout << dp[j] << " ";
// cout << endl;
len = max(len, pos + 1);
}
int k = len;
len = 1;
dp[0] = b[0];
for (int i = 1; i < n; ++i)
{
int pos = upper_bound(dp, dp + len, b[i]) - dp;
dp[pos] = b[i];
// for(int j=0;j<len;j++) cout << dp[j] << " ";
// cout << endl;
len = max(len, pos + 1);
}
// cout << k;
// cout << len;
int c = k>len?k:len;
cout << n-c <<endl;
return 0;
}