zoj 1986 || poj 1631 Bridging Signals(最长上升子序列N*logN)
2010-12-06 12:02
555 查看
和ZOJ 2316 差不多,不过这个是用单调队列+二分优化了,不优化过不去。
单调队列是保证里面元素是单调的,这样的话,取其中最大的值是O(1)的,如果有数比队尾元素小,就用二分查找,找到它的位置替换。
原理详见http://blog.csdn.net/Hashmat/archive/2010/09/14/5883605.aspx
我的二分写得比较纠结,改了好久才对 = =。。。
单调队列是保证里面元素是单调的,这样的话,取其中最大的值是O(1)的,如果有数比队尾元素小,就用二分查找,找到它的位置替换。
原理详见http://blog.csdn.net/Hashmat/archive/2010/09/14/5883605.aspx
我的二分写得比较纠结,改了好久才对 = =。。。
#include <stdio.h> #include <stdlib.h> #include <iostream> #include <string.h> using namespace std; int Q[40002]; int tail; int find(int low,int high,int x) { if( low = 1 && low == high ) if( x <= Q[1] ) return 1; else return -1; while( low <= high ) { int mid = (low+high)/2; if( Q[mid] <= x && Q[mid+1] >= x ) return mid+1; if( Q[mid] >= x ) high = mid; if( Q[mid] <= x ) low = mid+1; } return -1; } int main(void) { int ncases; int num[40002],n; scanf("%d",&ncases); while( ncases-- ) { cin >> n; tail = 1; memset(Q,0,sizeof(Q)); for(int i=1; i<=n; i++) scanf("%d",&num[i]); Q[tail] = num[1]; for(int i=2; i<=n; i++) { int x = find(1,tail,num[i]); if( x == -1 ) { tail++; Q[tail] = num[i]; } else Q[x] = num[i]; } printf("%d/n",tail); } return 0; }
相关文章推荐
- POJ 1631 Bridging signals DP(最长上升子序列)
- POJ 1631 Bridging signals (LIS:最长上升子序列)
- POJ 1631 最长上升子序列O(nlogn)
- POJ 1631 Bridging signals(最长上升子序列 n*logn && POJ 3903)
- POJ 1631 Bridging signals(LIS:最长上升子序列)
- POJ 1631 Bridging signals 解题报告(附详细分析)最长上升子序列的dp+二分
- poj 1631 Bridging signals 最长上升子序列的O(n*lgn)方法
- POJ 1631 —— Bridging signals 最长上升子序列
- POJ1631-Bridging signals-最长上升子序列
- poj1631 dp 最长上升子序列LIS
- zoj 1986(最长上升子序列)
- POJ 1631-Bridging signals(最长上升子序列+二分搜索)
- zoj1986,poj1631,最长上升子序列,复杂度O(n*logn)
- ZOJ 1986 最长上升子序列
- poj1631 Bridging signals 加强版最长上升子序列
- POJ1631——Bridging signals(动态规划,最长上升子序列应用)
- poj 1631离散化加树状数组优化 最长上升子序列LIS nlogn做法
- POJ 1631 Bridging signals 最长上升子序列
- POJ1631 最长上升子序列的新做法0(n)
- POJ 1631 Bridging signals [最长上升子序列O(nlog(n))]