T^T OJ 1388 最长上升子序列
Posted moxin0509
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了T^T OJ 1388 最长上升子序列相关的知识,希望对你有一定的参考价值。
长上升子序列
TimeLimit:1000MS MemoryLimit:64MB
64-bit integer IO format:%lld
已解决 | 点击收藏 | 已有4人收藏了本题
Problem Description
如果一个数列ai 满足 a1 < a2 < ... < aN 则这个数列被称作上升序列。
给定一个数列a(a1, a2, ..., aN)则任意一个数列b(ai1, ai2, ..., aiK)并且满足(1 <= i1 < i2 < ... < iK <= N).则b被称为a的子序列。
如果一个数列的子序列是上升序列,则这个序列称为原序列的上升子序列。
比如序列(1, 7, 3, 5, 9, 4, 8)的上升子序列有(1, 7), (3, 4, 8)等. 它的最长上升子序列长度是4,即(1, 3, 5, 8).
请你写一个程序求一个序列的最长上升子序列的长度。
Input
第一行是一个整数N表示给定数列的长度. 第二行包括N个范围在0~10000的整数。 1 <= N <= 1000
Output
输出一个整数表示最长上升子序列的最大长度
SampleInput
7 1 7 3 5 9 4 8
SampleOutput
4
【思路】:
复杂度为O(n*log(2)(n))的优化版本
#include<stdio.h> #include<algorithm> using namespace std; const int inf=1e9+7; int dp[41111];///dp[i] 最长上升子序列长度为i的时候 最小的尾数 int a[41111]; ///dp[pos]<=a[i]长度为pos的时候,最后一个数是<=a[i] ///dp[pos+1]=min(dp[pos+1],a[i]) ///dp[i]=MAX(dp[j]+1) j<i a[j]<a[i]; ///O(n^2)->O(n*log(n)) int efind(int s,int t,int x){ int l=s-1,r=t+1; while(l+1<r){ int mid=(l+r)/2; if(dp[mid]<=x) l=mid; else r=mid; } return l; }///找出第一个小于等于x的位置 int main(){ int t; scanf("%d",&t); while(t--){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",a+i); dp[1]=a[1]; int top=1; for(int i=2;i<=n;i++){ int pos=efind(1,top,a[i]); if(pos==top){ top++; dp[top]=a[i]; }else{ dp[pos+1]=min(dp[pos+1],a[i]); } } printf("%d\n",top); } return 0; }
以上是关于T^T OJ 1388 最长上升子序列的主要内容,如果未能解决你的问题,请参考以下文章