最长上升子序列
来源:互联网 发布:js调用手机相册插件 编辑:程序博客网 时间:2024/04/30 18:14
题意:
而nlogn得算法其实就是将枚举前i个数的每个数换成了当前最大上升子序列中,他a【i】可以排在哪里。
1759:最长上升子序列
- 总时间限制:
- 2000ms
- 内存限制:
- 65536kB
- 描述
- 一个数的序列bi,当b1 < b2 < ... <bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1,a2, ...,aN),我们可以得到一些上升的子序列(ai1,ai2, ...,aiK),这里1 <=i1 < i2 < ... <iK <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中最长的长度是4,比如子序列(1, 3, 5, 8).
你的任务,就是对于给定的序列,求出最长上升子序列的长度。 - 输入
- 输入的第一行是序列的长度N (1 <= N <= 1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000。
- 输出
- 最长上升子序列的长度。
- 样例输入
71 7 3 5 9 4 8
- 样例输出
4
最长上升子序列是DP中很基础的一个模型,但却很重要,因为在很多以后的题中都要用到他来解决问题,就像01背包一样,用来理解DP是非常不错的。
解题思路:
对于本题来说一共有两种常见的方法可解,一种是O(n^n)的,还有一种是O(nlogn)的解法。两种解法都是以前i个序列为阶段,以每个阶段的最长上升子序列的个数为状态,并且每次判断第i阶段中是否有新的子序列能使f【i】更新。f【i】为第i阶段的最大上升子序列的个数。
好先来说一下n^n的算法吧。每次枚举前i个数,并枚举前i个数中的每个数,以此来检查更新。
#include<iostream>#include<cstdio>using namespace std;int n;int a[1002];int f[1002];int main(){ scanf("%d",&n); for(int i = 1;i <= n; i++){ scanf("%d",&a[i]); f[i] = 1;//初始化每个数都为一个子序列,且长度为一。 } for(int i = 2;i <= n; i++){ for(int j = 1;j < i; j++){ if(a[j] < a[i]){//判断前i个数中假如有第j个数比他小,就相当于前j个数构成的最大上升子序列和第i个数可以构成一个更大的上升子序列。 f[i] = max(f[i],f[j]+1);//判断新构成的上升子序列是否比当前的大,大的更新。 } } } int ans = -9999999; for(int i = 1;i <= n; i++)ans = max(ans,f[i]);//找出最大的上升子序列。 printf("%d",ans);}
而nlogn得算法其实就是将枚举前i个数的每个数换成了当前最大上升子序列中,他a【i】可以排在哪里。
#include<iostream>#include<cstdio>using namespace std;int n;int a[1002];int c[1002];int find(int left,int right,int key){ while(left != right){ int mid = (left+right)/2; if(key <= c[mid])right = mid; else left = mid+1; } return left;}int main(){ scanf("%d",&n); for(int i = 1;i <= n; i++)scanf("%d",&a[i]); c[0] = -9999999; int len = 0; int j = 0; for(int i = 1;i <= n; i++){ if(a[i] > c[len])j = ++len;//c【len】为当前最大上升子序列上升中最大的一个数,如果a【i】任然比他大,则可构成新的最大上升子序列。 else j = find(1,len,a[i]);//如果a【i】比他小就判断在当前最大上升子序列中,能排在哪里。 c[j] = a[i];//跟新最大上升子序列,可以在后面加长,也可以使前面的跟小,如果前面的数越小,则后面的数跟容易比他大。 } printf("%d\n",len); //for(int i = 1;i <= len; i++)printf("%d ",c[i]);}
0 0
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- split用法举例
- 驱动调试之proc文件系统
- HTML5学习_day01(5)--css常见样式background
- 关于对webrtc的初次亲密接触的一点感想!
- Android 四种启动模式和 Activity 的 Flag
- 最长上升子序列
- Ajax请求下载文件
- unity5 测试导出场景和光照贴图丢失的问题
- (三)5阻塞型IO实现
- 输入子系统 input_match_device 匹配过程剖析
- blockhouses
- Activity过度动画应用
- 下拉菜单的实现,纯CSS实现下拉菜单 与 使用JS实现下拉菜单
- 小工具