poj 1631 Bridging signals 最长上升子序列的O(n*lgn)方法
2013-09-12 17:29
309 查看
在普通动规基础上,设一个数组d[i],表示到现在为止长度为i的子序列的末尾数字的最小值.显然对于求最长上升子序列由b[i-1] <= b[i] 则b为有序的,可以只用折半查找,从O(n)降到O(nlgn) 。整体时间由 O(n*n) 降到 O(n * lgn).
代码:
代码:
#include <stdio.h> #include <iostream> #include <cstring> using namespace std; int n; #define MAX_N 40001 int N[MAX_N]; int bl=0; int b[MAX_N]; int dp[MAX_N]; /* O(n2) int solve() { int ret =0; dp[0]=0; for(int i=1;i<=n;i++) { int maxl = 0; for(int j=1;j<i;j++) { if(N[j] < N[i] && dp[j] > maxl) maxl = dp[j]; } dp[i] = maxl+1; if(dp[i] > ret) ret = dp[i]; } return ret; } */ // O(n lg n) 优化 引入b 数组 // b[i] d[i],表示到现在为止长度为i的子序列的末尾数字的最小值. 显然对于求最长上升子序列由b[i-1] <= b[i] 则b为有序的,可以只用折半查找,从O(n)降到O(nlgn) 。整体时间由 O(n*n) 降到 O(n * lgn) // void dump() { printf("--------------- b is ------------\n"); for(int i=0;i<=bl;i++) { printf("[%d]=%d\t",i,b[i]); } printf("\n"); } int solve() { int ret =0; dp[0]=0; memset(b,0,sizeof(b)); b[0]=0; bl=0; for(int i=1;i<=n;i++) { int l=1,r=bl; int nl=0; while(l <= r) { int h=(l+r)/2; if(b[h] < N[i]) { l=h+1; } else if(b[h] > N[i]) { r=h-1; } } nl = l; dp[i] = nl; //dump(); //printf("N[%d]=%d l=%d nl=%d\n",i,N[i],l,nl); if( b[ nl] == 0) bl++; if( b[nl] == 0 || N[i] < b[ nl ] ) { //printf("\tb[%d]=%d\n\n",nl,b[nl]); b[ nl ] = N[i]; } } return bl; } int main() { int t; cin>>t; for(int _t=1;_t<=t;_t++) { cin>>n; for(int i=1;i<=n;i++) cin>>N[i]; cout<<solve()<<endl; } }
相关文章推荐
- POJ 1631 —— Bridging signals 最长上升子序列
- POJ 1631 最长上升子序列O(nlogn)
- POJ 1631 Bridging signals(LIS:最长上升子序列)
- poj1631 dp 最长上升子序列LIS
- POJ 1631-Bridging signals(最长上升子序列+二分搜索)
- POJ 1631 Bridging signals (LIS:最长上升子序列)
- POJ 1631 Bridging signals 最长上升子序列
- 动态规划(线性模型):POJ 1631 最长上升子序列
- poj 1631离散化加树状数组优化 最长上升子序列LIS nlogn做法
- poj1631 Bridging signals 加强版最长上升子序列
- POJ1631 最长上升子序列的新做法0(n)
- POJ 1631 Bridging signals 解题报告(附详细分析)最长上升子序列的dp+二分
- POJ1631-Bridging signals-最长上升子序列
- POJ 1631 Bridging signals DP(最长上升子序列)
- zoj 1986 || poj 1631 Bridging Signals(最长上升子序列N*logN)
- poj - 1631 最长上升子序列 Java
- POJ1631——Bridging signals(动态规划,最长上升子序列应用)
- POJ 1631 Bridging signals [最长上升子序列O(nlog(n))]
- POJ 2127 Greatest Common Increasing Subsequence (最长公共上升子序列+记录路径)
- HDU 1087 && POJ 2533(DP,最长上升子序列).