从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的

来源:互联网 发布:普通话测试软件免费版 编辑:程序博客网 时间:2024/04/28 08:48
/**copyright@nciaebupt 转载请注明出处*问题:从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的(网易)。*比如数列1,4,3,5,6,7,2,0 删除的最少的数的个数为1*求解思路:双端LIS问题,使用动态规划的思路求解,时间复杂度O(nlog(n))*/#include <cstdio>#include <iostream>using namespace std;int DoubleEndLIS(int *array,int len){    int left,mid,right;    int max=0;    int k =0;    //LIS数组中存储的是 递增子序列中最大值最小的子序列的最后一个元素(最大元素)在array中的位置    int *LIS = new int[len];    //从左到右LIS中最长子序列中最大值最小的子序列的最后一个元素所在的位置,也就是0~i的数字序列中最长递增子序列的长度-1    int *B = new int[len];    //从右到左LIS中最长子序列中最大值最小的子序列的最后一个元素所在的位置,也就是len-1~i的数字序列中最长递增子序列的长度-1    int *C = new int[len];    //从左到右    for(int i = 0;i < len;++i)//LIS数组清零    {        B[i] = 0;        LIS[i] = 0;    }    LIS[0] = array[0];    for(int i = 1;i < len;++i)    {        left = 0;        right = B[k];        while(left <= right)        {            mid = (left + right)/2;            if(array[i] < LIS[mid])            {                right = mid - 1;            }            else            {                left = mid + 1;            }        }        LIS[left] = array[i];//将array[i]插入到LIS中        if(left > B[k])        {            B[k+1] = B[k] + 1;            k++;        }    }    for(int i = 0;i < k;++i)    {        B[i]++;    }    //从右到左    for(int i = 0;i < len;++i)//LIS数组清零    {        C[i] = 0;        LIS[i] = 0;    }    k = 0;    LIS[0] = array[len-1];    for(int i = len-2;i >= 0;--i)    {        left = 0;        right = C[k];        while(left <= right)        {            mid = (left + right)/2;            if(array[i] < LIS[mid])            {                right = mid - 1;            }            else            {                left = mid + 1;            }        }        LIS[left] = array[i];        if(left > C[k])        {            C[k+1] = C[k] + 1;            k++;        }    }    for(int i = 0;i <= k;++i)    {        C[i]++;    }    //求max    for(int i = 0;i < len;++i)    {        //cout<<B[i]<<"  "<<C[i]<<endl;        if(B[i]+C[i]>max)            max=B[i] + C[i];    }    return len - max +1;}int main(int args,char ** argv){    int array[] = {1,4,3,5,6,7,2,0};    int len = sizeof(array)/sizeof(int);    int res = DoubleEndLIS(array,len);    cout<<res<<endl;    getchar();    return 0;}

原创粉丝点击