#include <iostream>
using namespace std;
int DoubleEndLIS(int *arr, int len)
{
int *LIS = new int[len];
int *lefToRight = new int[len]; //leftToRight[i]表示0~i最长子序列长度-1
int *rightToLeft = new int[len];
int maxLen = 0; //记录总共的(上升+下降)最长子序列长度
int low, high, mid;
for (int i = 0; i < len; ++i)
{
lefToRight[i] = 0;
LIS[i] = 0;
}
LIS[0] = arr[0];
for (int i = 1; i < len; i++)
{
low = 0; high = lefToRight[i-1];
while (low <= high)
{
mid = (low + high)/2;
if (LIS[mid] < arr[i])
{
low = mid + 1;
}
else
{
high = mid -1;
}
}
LIS[low] = arr[i];
if (low > lefToRight[i-1])
{
lefToRight[i] = lefToRight[i-1] + 1; //最长子序列长度加1
}
else
{
lefToRight[i] = lefToRight[i-1];
}
}
//leftToRight的每个值增加1,因为他们是最长子序列值-1
//此时leftToRight表示的是最长子序列的真正值。
for (int i = 0; i < len; i++)
{
lefToRight[i]++;
}
//从右到左
for (int i = 0; i < len; i++)
{
rightToLeft[i] = 0;
LIS[i] = 0;
}
int k = 0;
LIS[0] = arr[len-1];
for (int i = len -2; i >= 0; --i)
{
low = 0; high = rightToLeft[k];
while (low <= high)
{
mid = (low + high)/2;
if (LIS[mid] < arr[i])
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
LIS[low] = arr[i];
if (low > rightToLeft[k])
{
rightToLeft[k+1] = rightToLeft[k] + 1;
}
else
{
rightToLeft[k+1] = rightToLeft[k];
}
++k;
}
for (int i = 0; i < k; ++i)
{
rightToLeft[i]++;
}
//求最大值即为要求的
for (int i = 0; i < len; ++i)
{
cout<<"i: "<<i<<" "<<lefToRight[i]<<" "<<rightToLeft[len-i-1]<<endl;
if (lefToRight[i] + rightToLeft[len-i-1] > maxLen)
maxLen = lefToRight[i] + rightToLeft[len-i-1];
}
cout<<"maxLen:"<<maxLen<<endl;
delete LIS;
delete lefToRight;
delete rightToLeft;
return len - maxLen + 1;
}
int main()
{
int arr[] = {1,5,7,6,9,3,8,4,2};
int ret;
ret = DoubleEndLIS(arr, 9);
cout<<ret<<endl;
return 0;
}