从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的(网易)。
2014-10-08 20:48
176 查看
题目描述:
从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的(网易)。
分析:
这可以用双端LIS方法来解决,先求一遍从左到右的,再求一遍从右到左的。最后从里面选出和最大的即可。
代码实现:
参考:http://blog.csdn.net/nciaebupt/article/details/8466049
但是,他的程序有问题,我做了修改。
从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的(网易)。
分析:
这可以用双端LIS方法来解决,先求一遍从左到右的,再求一遍从右到左的。最后从里面选出和最大的即可。
代码实现:
#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; }
参考:http://blog.csdn.net/nciaebupt/article/details/8466049
但是,他的程序有问题,我做了修改。
相关文章推荐
- 从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的(网易)。 题目描述:
- 从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的
- 从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的。
- 从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的。
- 从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的
- 从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的
- 从一列数中筛除尽可能少的数,使得从左往右看这些数是从小到大再从大到小
- 从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的
- 【幂数列】设x,y为非负整数,试计算集合M={2^x*3^y|x>=0,y>=0}的元素小于指定整数n的个数, 并求这些元素从小到大序列的第m项。
- 写一个函数,尽可能高效的,从一个标准 url 里取出文件的扩展名
- 网易Java程序员两轮面试,这些问题你能答对几个?
- poj 1236 Network of Schools 1)至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点 2)至少要加多少条边,才能使得从任何一个顶点出发,都能到达全部顶点
- 大数据,人工智能网易百度这些公司都走在前列
- hdu 2546 01背包(从一堆物品中尽可能组成接近给定重量的方案)
- UVA10160在一个图中选择几个点,使得这些点加上相邻的点为这个图的顶点集
- 【Codeforces Round 169 (Div 2) D】【简单数位贪心】Little Girl and Maximum XOR 区间选两数使得异或值尽可能大
- 设计队列容器的数据结构,使得返回最大元素的操作时间复杂度尽可能的低。
- 从一道网易面试题浅谈OC线程安全
- 【Codeforces Round 374 (Div 2)D】【贪心】 Maxim and Array n个数做K次±X使得乘积尽可能小
- Lily上课时使用字母数字图片教小朋友们学习英语单词,每次都需要把这些图片按照大小(ASCII码值从小到大)排列收好。请大家给Lily帮忙,通过C语言解决。