//最长递增子序列(LIS)和最长递减子序列(LDS)的解法其实是一样的,题目就是要求需要改动的次数最少,所以只要
//求出其序列的最长递增子序列和最长递减子序列,通过比较就可以最长的子序列,从而就可以求出改动次数最少答案了!
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <climits>
#include <algorithm>
using namespace std;
const int MAX = 30001;
int num[MAX], tmp[MAX];
int main()
{
int i, n, ans, ans1, ans2, left, right, mid;
scanf("%d", &n);
for (i = 0; i < n; i++){
scanf("%d", &num[i]);
}
//最长递增子序列的求解
memset(tmp, 0, sizeof(tmp));
tmp[0] = -1;
ans1 = 0;
for (i = 0; i < n; i++){
//这里是要判断是否有相等的,因为题目只是给出了1到3的数,而它的递增序列可以是112233这样的形式!
if (num[i] >= tmp[ans1]){
tmp[++ans1] = num[i];
}
else {
left = 1, right = ans1;
while (left <= right){
mid = (left + right) / 2;
if (num[i] >= tmp[mid]){
left = mid + 1;
}
else{
right = mid - 1;
}
}
tmp[left] = num[i];
}
}
//最长递减子序列的求解
memset(tmp, 0, sizeof(tmp));
tmp[0] = INT_MAX;
ans2 = 0;
for (i = 0; i < n; i++){
if (num[i] <= tmp[ans2]){
tmp[++ans2] = num[i];
}
else {
left = 1, right = ans2;
while (left <= right){
mid = (left + right) / 2;
if (num[i] <= tmp[mid]){
left = mid + 1;
}
else{
right = mid - 1;
}
}
tmp[left] = num[i];
}
}
//cout << ans1 << " " << ans2 << endl;
ans = n - max(ans1, ans2);
cout << ans << endl;
system("pause");
}
/*
5
1
1
2
3
1
*/
04-11
04-11