nlogn求最长上升子序列 (POJ2533)
来源:互联网 发布:上海迈博软件 编辑:程序博客网 时间:2024/06/10 02:52
nlogn求最长上升子序列 (POJ2533)
Description
求最长上升子序列。
题解
LIS裸题,但我这里想讲一下nlogn的做法。
其实我们可以发现,在通常的LIS算法中的的二个循环的过程中,为了寻找最大值,做了很多无用功。
于是,我们可以用一个单调栈来作为决策列表,用logn的时间来找到最优决策。
对于一个数,如果其大于栈定元素,就将其加入栈,以其结尾的答案就是栈的大小。这就代表着这个数可以取之前栈定元素作为决策,所以长度为之前栈定元素的长度加一。于是,这个数也成为这个长度下第一个也是目前唯一一个决策来入栈。
如果这个数小于栈定,用lower_bound来找到栈第一个大于等于这个数的元素,令其为栈中序号为k,这个数的长度就算k-1的长度加一,也就是k的长度。
因为这个数有比找到数的值小,将其着为以后的决策当然可以更优,我们就用它来替换找到的数。
这样维护了一个单调的决策栈,可以花logn的时间决策,总复杂度为nlogn。
答案就算栈的大小,也就是以栈定元素结尾的大小。
#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#define MAXN 1000000+10using namespace std;int n,a[MAXN],f[MAXN],ans=1,top=1;int s[MAXN],d[MAXN];int main(){ while(scanf("%d",&n)!=EOF) { memset(a,0,sizeof(a)); for(int i=1;i<=n;i++) scanf("%d",&a[i]); memset(s,0,sizeof(s)); ans=1;top=1;s[top]=a[1]; for(int i=2;i<=n;i++) { if(a[i]>s[top]) s[++top]=a[i]; else s[lower_bound(s+1,s+top+1,a[i])-s]=a[i]; } printf("%d\n",top); } return 0;}
0 0
- nlogn求最长上升子序列 (POJ2533)
- POJ2533, 最长上升子序列(贪心+二分查找时间复杂度O(nlogn))
- POJ2533(最长上升子序列)
- poj2533:最长上升子序列
- 最长上升子序列 POJ2533
- poj2533 最长上升子序列
- POJ2533最长上升子序列
- 最长上升子序列 (二分 nlogn)
- 最长上升子序列详解(nlogn)
- 最长上升子序列(nlogn算法)
- 最长上升子序列 nlogn
- nlogn 最长上升子序列
- 最长上升子序列(nlogn)
- Nlogn最长上升子序列
- poj3903--Stock Exchange--nlogn贪心求最长上升子序列
- poj2533--Longest Ordered Subsequence(dp:最长上升子序列)
- poj2533 Longest Ordered Subsequence(最长上升子序列)
- poj2533 Longest Ordered Subsequence(最长上升子序列个数)
- C语言名企面试题2
- Python正则匹配
- vue.js 过滤器传参数及接收
- hbase系统架构
- 二分+最小生成树
- nlogn求最长上升子序列 (POJ2533)
- Java源码阅读的真实体会
- 折半查找代码的编写和探索
- ajax
- 利用Linux命令行进行文本按行去重并按重复次数排序
- 文件描述符(fd)与FILE结构体
- 常用sql语句
- c++11 union
- [PAT-乙级]1009.说反话