最长上升子序列
来源:互联网 发布:数据分析技术 编辑:程序博客网 时间:2024/06/09 13:42
最长上升的O(n^2)的方法是我看过最简单的DP了~~
拿POJ 2533来说。
Sample Input
7
1 7 3 5 9 4 8
Sample Output(最长上升/非降子序列的长度)
4
从输入的序列中找出最长的上升子序列(LIS)。
d(i)=max(1,d(j)+1)其中(a[i]>a[j])其中这里的i,j均为下标。含义是讨论到第i个数的最长上升子序列,要么是1,即都比前面的小,否则一定是由前面某一个dp(j)其中(a[j]<a[i])加1得到.
当然最后得到的总体的最长上升序列的长度为dp数组中的最大值,注意不是最后一个比如2,3,5,1前面3个数,每一个数的dp都是由前面的dp中最大+1继承而来,而最后一个比前面每一个数都小。
#include <stdio.h>#include <string.h>int dp[10001];int a[1001]; int main() { int n,m,i,j,max; while(scanf("%d",&n)==1) { memset(a,0,sizeof(a)); memset(dp,0,sizeof(dp)); for (i=1;i<=n;i++) scanf("%d",&a[i]); max=0; for (i=1;i<=n;i++) { dp[i]=1; for (j=1;j<=i-1;j++) if ((a[j]<a[i])&&(dp[i]<dp[j]+1))//每一次只需要加那个前面dp(j)的最高一次,而如果加了就是dp(i)=dp(j)+1即如果dp(i)如果小于dp(j)+1就要更新,否则肯定保持当前较大的dp(i) { dp[i]=dp[j]+1; } if (dp[i]>max) max=dp[i]; } printf("%d\n",max); } return 0; }
这个解法不是我想的,从网上学来的,这里面与大家分享一下。这个算法的复杂度只有O(nlogn),在有大量数据的情况下,这算法效率极高。。。
(摘录原作者的话)
这个算法其实已经不是DP了,有点像贪心。至于复杂度降低其实是因为这个算法里面用到了二分搜索。本来有N个数要处理是O(n),每次计算要查找N次还是O(n),一共就是O(n^2);现在搜索换成了O(logn)的二分搜索,总的复杂度就变为O(nlogn)了。
这个算法的具体操作如下(by RyanWang):
开一个栈,每次取栈顶元素top和读到的元素temp做比较,如果temp > top 则将temp入栈;如果temp < top则二分查找栈中的比temp大的第1个数,并用temp替换它。 最长序列长度即为栈的大小top。
这也是很好理解的,对于x和y,如果x < y且Stack[y] < Stack[x],用Stack[x]替换Stack[y],此时的最长序列长度没有改变但序列Q的''潜力''增大了。
举例:原序列为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 <stdio.h>int s[1001]; int main() { int i,n,top,temp; while(scanf("%d",&n)==1) { top=0; s[top]=-1;//保证最小 for (i=1;i<=n;i++) { scanf("%d",&temp); if (temp>s[top])//如果比栈顶元素大则入栈成为栈顶元素 s[++top]=temp; else//否则二分查找比temp大的第一个数 { int low=1; int high=top; int middle; while(low<=high) { middle=(low+high)/2; if (s[middle]<temp) low=middle+1; else high=middle-1; } s[low]=temp;//用temp代替比temp大的第一个数代替,总数不变 } } printf("%d\n",top); } return 0; }
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 共同构建网络空间命运共同体
- maven 插件开发
- 这两天的设计入门知识的学习总结
- 如何在ubuntu下安装flash
- Redis文件事件处理用到的基本数据结构视图
- 最长上升子序列
- 软件渲染器、内存文件系统
- hdu 2577 How to Type (动态规划 入门好题)
- bzoj2565(manachery)
- CCF-201509-2
- Qt 打开文件引发的种种操作方法!
- iOS开发UI篇—Quartz2D使用(绘图路径)
- poj 1321 棋盘问题 dfs暴力
- Swift数据类型