POJ2533 DP入门级题目-最大上升子序列(LIS)-O(n^2)与O(nlogn) (变形,POJ1631)
来源:互联网 发布:淘宝美工一个月多少钱 编辑:程序博客网 时间:2024/05/21 07:57
0
O(nlogn)复杂度的 方法2)很重要,要掌握。
1
1)时间复杂度为O(N^2),原理是不断更新每个元素作为最后一个元素的各自序列的长度
#include <iostream>//入门DP问题,时间复杂度O(N^2)using namespace std;int main(){ int a[1010];//输入元素 int d[1010];//d[i]代表以a[i]为最后一个元素的序列的长度 int n;cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; d[i]=1; } int maxn=0; for(int i=1;i<=n;i++){ for(int j=1;j<=i-1;j++){ if(a[j]<a[i]&&d[i]<d[j]+1){//动态更新每一个元素作为最后一个元素的所构造的序列的长度 d[i]=d[j]+1; } } if(d[i]>maxn) maxn=d[i];//顺便记录最大值 } cout<<maxn<<endl;}
2)时间复杂度为O(nlogn),构造一个数组d用来保存一个近似的最大上升子序列(不一定是真正的最长子序列,但是长度与最长子序列相同,因为每一次更新替换序列里某个数时,长度不变,序列潜力变大),用二分法查找序列里的数则降低了时间复杂度。
(即一个一个元素插入单调递增的队列,如果发现后者比当前的队尾元素大那么插入队尾,否则二分查找到比他大的最小值那个位置,替换掉即可。)
#include <iostream>#include <cstdio>using namespace std;int len; int a[1010],d[1010];int update(int k){ int l=1,r=len; int mid; while(l<=r){ mid=(l+r)/2; if(d[mid]<k){ l=mid+1; } else if(d[mid]>k){ r=mid-1; } else{ return mid; } } return l;//返回 l 和 返回 r 是不一样的,注意!}int main(){ int n;cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } len=1;d[1]=a[1]; for(int i=2;i<=n;i++){ int position=update(a[i]); d[position]=a[i]; if(position>len) len++; } cout<<len<<endl; return 0;}
3)疑惑???为什么同样用构造一个数组来保存近似的最大上升子序列时,但不用二分法搜,倒序遍历就会WA、??,原理同2)一样,不过时间复杂度变成O(n^2)为什么就过不了呢?1)中也是O(n^2)但是过了呀!
求解释,0.0
#include <iostream>#include <cstdio>using namespace std;int len; int a[1010],d[1010];int update(int k){ for(int j=len;j>0;j--){ if(d[j]<k){ return j+1; } }}int main(){ int n;cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } len=1;d[1]=a[1]; for(int i=2;i<=n;i++){ int position=update(a[i]); d[position]=a[i]; if(position>len) len++; } for(int k=1;k<=len;k++) cout<<d[k]<<" "; return 0;}
#include <iostream>using namespace std;int main(){ int a[1010],d[1010]; int n;cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } int top=1;d[1]=a[1]; for(int i=2;i<=n;i++){ if(d[top]<a[i]){//扩展序列长度 d[++top]=a[i]; } else{//更新已经选进序列的字符,使改序列保持最大潜力 for(int j=top-1;j>0;j--){ if(d[j]<a[i]){ d[j+1]=a[i]; break; } } } } cout<<top<<endl; return 0;}
0 0
- POJ2533 DP入门级题目-最大上升子序列(LIS)-O(n^2)与O(nlogn) (变形,POJ1631)
- 最长上升子序列(LIS)长度的O(n^2)与O(nlogn)算法
- 【LIS最长上升子序列】O(n^2)与O(nlogn)算法(HDU1257)
- 【最长上升子序列LIS】O(n^2)和O(nlogn)算法简记
- 动态规划--最长上升子序列问题(LIS) O(n^2) ,O(nlogn)
- LIS最长上升子序列O(n^2)&O(nlogn)
- 最长上升子序列(LIS)的O(nlogn) & O(n^2)算法
- 最长上升子序列、最长下降子序列的DP算法由O(n^2)到O(nlogn)算法
- 最长上升子序列LIS集合 POJ2533,POJ1631,POJ1887,POJ1609
- poj1631 dp 最长上升子序列LIS
- 最长上升子序列(LIS)长度的O(nlogn)算法
- 优化的最长上升子序列LIS算法 O(nlogn)
- 最长上升子序列(LIS)长度的O(nlogn)算法 .
- 最长上升子序列(LIS)长度的O(nlogn)算法
- 最长上升子序列(LIS)长度的O(nlogn)算法
- 最长上升子序列(LIS)长度的O(nlogn)算法
- 最长上升子序列(LIS)长度的O(nlogn)算法
- 最长上升子序列(LIS)长度的O(nlogn)算法
- 求n的阶乘后导0的个数
- POJ-2115-C Looooops-扩展欧几里德算法
- 1065. A+B and C (64bit) (20)
- 堆和栈的区别
- vim 解决中文乱码,设置高亮,共享粘贴板
- POJ2533 DP入门级题目-最大上升子序列(LIS)-O(n^2)与O(nlogn) (变形,POJ1631)
- BZOJ3998: [TJOI2015]弦论
- 记录重要博客链接
- 关于滴水的VT调试器 by 海风月影
- 51nod(1183)——dp
- iOS 开发 -- Swift (十二) 懒加载
- iOS-OC-基本控件之UIPageControl
- OpenGL入门学习(十三)
- iOS文件解析之XML解析