POJ 2533 Longest Ordered Subsequence - from lanshui_Yang
来源:互联网 发布:淘宝上iphone裸机 编辑:程序博客网 时间:2024/06/11 23:36
题目大意:求一个数列的最长上升子序列(严格上升)。
解题思路:
方法一:O(n^2)
dp[i]:表示处理到第i个位置,序列的最长上升子序列末尾为i的长度; a[]数组存储原序列
dp[i] = max{dp[j]+1},a[i]>a[j],0≤j≤i
方法二:O(nlogn)
复杂度降低其实是因为这个算法里面用到了二分搜索。本来有N个数要处理是O(n),每次计算要查找N次还是O(n),一共就是O(n^2);现在搜索换成了O(logn)的二分搜索,总的复杂度就变为O(nlogn)了。
这个算法的具体操作如下:
开一个栈,每次取栈顶元素top和读到的元素temp做比较,如果temp > top 则将temp入栈;如果temp < top则二分查找栈中的比temp大的第1个数,并用temp替换它。最长序列长度即为栈的大小top。
道理:对于数列中的a[i] 和a[j] ,i < j , 假设a[ i ]已在栈stap中,a[ j ] 未在栈中,这时读到元素a[ j ] , 如果a[ j ] < a[ i ](此时a[j]必然小于栈顶元素), 将a[j]与 a[i] 互换,此时这个栈的大小没有变化,但这个栈的“潜力”变大了,因为如果存在a[ j ] < a[ z ] < a[ i ] (i < j < z) ,当a[ i ]为栈顶元素时,a[ j ] 替换 a[ i ]后成为栈顶元素,此后在读到a[ z ] 时就能把a[z] 压入栈,栈的大小就增加 1 , 即最长上升子序列长度就增加了1。
举例:原序列为1,5,8,3,6,7
栈为1,5,8,此时读到3,用3替换5,得到1,3,8; 再读6,用6替换8,得到1,3,6;再读7,得到最终栈为1,3,6,7。最长递增子序列为长度4。
请看代码:
#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<algorithm>#include<cmath>using namespace std ;const int MAXN = 1e3 + 5 ;int s[MAXN] ;int dp[MAXN] ;int n ;int stap[MAXN] ;int top ;void init(){ int i , j ; for(i = 1 ; i <= n ; i ++) { scanf("%d" , &s[i]) ; }}void solve() // O(n^2) 算法{ int i , j ; dp[1] = 1 ; for(i = 2 ; i <= n ; i ++) { dp[i] = 1 ; for(j = 1 ; j < i ; j ++) { if(s[i] > s[j] && dp[i] < dp[j] + 1) { dp[i] = dp[j] + 1 ; } } } int MAX = -1 ; for(i = 1 ; i <= n ; i ++) { if(MAX < dp[i]) MAX = dp[i] ; } printf("%d\n" , MAX) ;}void solve2() // O(n log n) 算法{ top = 0 ; stap[++ top] = s[1] ; int i ; for(i = 2 ; i <= n ; i ++) { if(s[i] > stap[top]) { stap[++ top] = s[i] ; } else if(s[i] < stap[top]) { int left , right , mid ; left = 1 ; right = top ; while (left < right) { mid = (left + right) / 2 ; if(stap[mid] < s[i]) { left = mid + 1 ; } else if(stap[mid] == s[i]) { break ; } else { right = mid ; // 注意不是 mid - 1 !! } } mid = (left + right) / 2 ; stap[mid] = s[i] ; } } printf("%d\n" , top) ;}int main(){ while (scanf("%d" , &n) != EOF) { init() ; //solve() ; solve2() ; } return 0 ;}
- POJ 2533 Longest Ordered Subsequence - from lanshui_Yang
- POJ 2533 Longest Ordered Subsequence
- poj 2533Longest Ordered Subsequence
- poj 2533 Longest Ordered Subsequence
- Poj 2533 Longest Ordered Subsequence
- poj 2533 Longest Ordered Subsequence
- poj 2533 Longest Ordered Subsequence
- POJ 2533 Longest Ordered Subsequence
- POJ 2533 Longest Ordered Subsequence
- POJ 2533 Longest Ordered Subsequence
- POJ 2533 Longest Ordered Subsequence
- poj 2533 Longest Ordered Subsequence
- POJ 2533 Longest Ordered Subsequence
- POJ 2533 Longest Ordered Subsequence
- poj 2533 Longest Ordered Subsequence
- POJ 2533 Longest Ordered Subsequence
- POJ 2533 Longest Ordered Subsequence
- POJ 2533 : Longest Ordered Subsequence
- IOS开发中nil和release的用法 以及nil和 null的使用
- 服务器进程fork()两次的原因
- 基于jeasyui的遮罩扩展[修复链式bug]
- ContentObserver回调与ContentProvider注册notifychange
- ActiveMQ
- POJ 2533 Longest Ordered Subsequence - from lanshui_Yang
- tomcat最大连接数的设置
- zero和null及sparse文件
- 佛曰
- hadoop0.23 源码编译 错误及原因
- JSP学习笔记(一)
- JSON格式详解
- CSS Hack
- Linux命令行的一些要点(三)