首页 > 代码库 > 单调递增子序列(二)(南阳oj214)
单调递增子序列(二)(南阳oj214)
单调递增子序列(二)
时间限制:1000 ms | 内存限制:65535 KB
难度:4
- 描述
给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序列,并求出其长度。
如:1 9 10 5 11 2 13的最长单调递增子序列是1 9 10 11 13,长度为5。
- 输入
- 有多组测试数据(<=7)
每组测试数据的第一行是一个整数n表示序列中共有n个整数,随后的下一行里有n个整数,表示数列中的所有元素.每个整形数中间用空格间隔开(0<n<=100000)。
数据以EOF结束 。
输入数据保证合法(全为int型整数)! - 输出
- 对于每组测试数据输出整形数列的最长递增子序列的长度,每个输出占一行。
- 样例输入
7 1 9 10 5 11 2 13 2 2 -1
- 样例输出
5 1
- 来源
- [521521]改编
- 上传者
ACM_赵铭浩
经典代码超时,复杂度(n*n)。
#include<stdio.h> #include<algorithm> using namespace std; int a[100010]; int dp[100010]; int main() { int i,j,n; while(scanf("%d",&n)!=EOF) { for(i=0;i<n;i++) { scanf("%d",&a[i]); dp[i]=1; } for(i=n-2;i>=0;i--) { for(j=i+1;j<n;j++) { if(a[i]<a[j]&&dp[i]<dp[j]+1) dp[i]=dp[j]+1; } } sort(dp,dp+n); printf("%d\n",dp[n-1]); } return 0; }
二分查找,复杂度n(logn)可以飘过!详细算法参考: 最少拦截系统(杭电1257)
#include<stdio.h> #include<string.h> int a[100010]; int s[100010]; int len,i; int search(int i) { int left=1,right=len; while(left<right) { int mid=(left+right)/2; if(s[mid]>a[i]) right=mid; else if(s[mid]==a[i]) return mid; else left=mid+1; } return left; } int main() { int j,n; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) scanf("%d",&a[i]); len=1; s[len]=a[1]; for(i=2;i<=n;i++) { if(a[i]>s[len]) { len++; s[len]=a[i]; } else { j=search(i); s[j]=a[i]; } } printf("%d\n",len); } return 0; }
单调递增子序列(二)(南阳oj214)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。