Longest Increasing Subsequence
来源:互联网 发布:maclc如何安装windows 编辑:程序博客网 时间:2024/04/25 16:26
最长递增(递减)子序列问题,wangs说十分重要,在许多题目中,都会遇到此类问题的变形,我记得去年我在刷CF的时候,就遇到此类题目,当日还没学动态规划,尝试用贪心去解决,果断的超时。看了一份资料是关于动态规划的,第一个就讲的是最长子序列问题。查了一些资料,有了一些理解。
在查资料之前,我推出的公式是:d[i]=d[j]+1,当j<i&&A[j]<A[i],其实思路是没错,但是应当考虑的是,在i之前的所有序列都应该遍历一遍,从而取最大值。
所以正确的递推公式应该是:d[i]=max(d[j]+1), j<i&&j>0&&A[j]<A[i]; 因为在考虑到第i个时,如果第i个能够加入,那么我们就必须考虑到A[I]大于前面的子序列中的最大值,并且,我们得取前面的子序列长度的最大值,即转化到子问题前i-1项中小于等于A[I]的序列的最长序列。
按照我的想法实现方法应该如下:
int LIS(){ int i,n,l; for(i=0;i<5;i++) d[i]=1; for(i=0;i<5;i++) for(int j=0;j<i;j++) { if(a[i]>=a[j]) d[i]=max(d[i],d[j]+1); } for(i=0;i<5;i++) if(l<d[i]) l=d[i]; return l;}
很明显该算法的复杂度是O(n^2);查了一些资料,还找到一个O(n^2)的递推公式,这个公式把我折磨惨了,花了一个晚上都没搞明白,最后还是学长一句话点醒我。
下面给大家介绍下我在另外一个博客看到的,虽然都是O(n^2)的算法,而且此算法将问题复杂化,但是我觉得把每一个正确的读懂,有利于思维吧!
假设现在给定一个序列A,我们自己定义一个序列B,其中B是由A序列拷贝过来的,并且B序列经过排序得到是in order。
现在我们假设S[i][j]表示在前i项中,且元素的最大值是B[j]的最长子序列的长度。
First : copy A to B;
:make B in order ,
:init S [1][j] ,j from 1 to n{ if(A[i]>B[j]) S[1][j]=0 else S[1][j]=1 }
Then i -> 2 to n;
j-> 1 to n;
if(A[i]>b[j]) S[i][j]=s[i-1][j] 因为此时A[I]>B[j],而S[i][j]表示的是前i项中小于等于B[j]的最长子序列大小,固A[i]是不能加入
else
find the index k of A[i] in the B;
S[i][j]=max(S[i-1][j],S[i-1][k]+1) 其实我纠结的地方是为什么这里是在K点,后来想明白,因为如果超过K点就可能导致A[I]小于B[j],而S[i][h](h>k)中的最大数就会大于A[i]。从而导致不能构成递增、这点坑了我好久。。。
对于一般的数据,或许O(n^2)的算法能够算过,但是当数据范围增大时,就会导致时间超限,所以我们这里需要的是优化时间,
二分法:
首先,我们需要明白一个道理,对于i项中,设最长的递增子序列的长度为s;
设c数组中存的是长度有1-s的子序列的最大值。那么这个数组一定是递增的。
设i-1项中,最长的递增子序列和为s;且最大的是c[s];
如果当前元素小于c[s],我们就在里面找一个比他第一小的,替换掉他。
这样的话就相当于压缩,减小规模,增加了后面的序列可增加性,
但是当前元素大于的话,那么说明长度增加1,并且把当前的值赋值给c[s+1];
int longest_increasing_sequence(int a[4000],int n){ int i,j,k,ans,m; ans=0; for(i=n;i>=1;i--) { j=1; k=ans; while(j<=k) { m=(j+k)/2; if(b[m]>a[i]) j=m+1; else k=m-1; } if(j>ans) ans+=1; b[j]=a[i]; } return ans;}
至于记录路径的神马的,明天再说吧!确实累了,今天一天就琢磨这一个题目。。。
人笨就是没办法啊!~~~
端午节到了!明天好好学一天算法,后天高数,外天大物,
Power Yes!KItty
- Longest Increasing Subsequence
- 【DP】 Longest Increasing Subsequence
- Longest Increasing Subsequence(LIS)
- Longest Increasing Subsequence
- 【算法】Longest Increasing Subsequence
- Longest Increasing Subsequence
- Longest Increasing Subsequence
- Longest Increasing Subsequence
- Longest Increasing Subsequence
- Longest Increasing Subsequence(LIS)
- Longest Increasing Subsequence
- [DP]Longest Increasing Subsequence
- The Longest increasing subsequence
- [刷题]Longest Increasing Subsequence
- longest-increasing-subsequence
- Longest Increasing Subsequence
- codeforces568E.Longest Increasing Subsequence
- Longest Increasing Subsequence
- 错过这篇文章,可能你这辈子不懂什么叫傅里叶变换了(一)
- android audiorecord
- [Python]Multiprocessing vs Threading Python
- 错过这篇文章,可能你这辈子不懂什么叫傅里叶变换了(二)
- 使用函数指针,完成一个sort()函数,能对任何类型的数组元素进行排序: 回调函数 以及 memcpy ()原型实现
- Longest Increasing Subsequence
- 意尔康:连锁专卖店如何实现集中式管理
- linux常用命令
- 好用的画图工具 octave
- js页面跳转整理
- ObjectARX学习笔记(十六)--如何设置CAD选项对话框的配置AcApProfileManagerReactor反应器
- P2000、MSA1040、MSA2040存储容量比较
- Linux挂载移动硬盘、U盘
- MFC对话框增加最大化和最小化按钮