题目大意:求最长上升子序列(LIS)长度,序列最大数不超过40000。因为只有上升排列的接口才不相交。
思路:普通的 O(n^2)的做法肯定会超时;因此,dp[ ] 记录长度为 i+1 的子序列中最末元素的最小值,这一数组是单调递增的,因此对于dp[ ]数组内元素可以用二分搜索找出dp[ ]中比 a[ i ] 大的最小的元素的位置;这里用到了STL类里的 lower_bound(x, x+n, k)函数(http://www.cplusplus.com/reference/algorithm/lower_bound/?kw=lower_bound)函数返回排好序的序列 x[ ] 中满足 x[ i ] >= k 的 x[ i ] 的最小指针。
AC代码如下:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define M 40010 #define INF 1000000 int dp[M],a[M]; void init(int *a, int n) { for(int i = 0; i < n; i++) { a[i] = INF; } } int main() { int n; scanf("%d",&n) == 1; while(n--) { int x; scanf("%d",&x); for(int i = 0; i < x; i++) scanf("%d",&a[i]); init(dp,x); for(int i = 0; i < x; i++) *lower_bound(dp, dp+x, a[i]) = a[i]; cout<<lower_bound(dp, dp+x, INF) - dp<<endl; } return 0; }
作者:u011652573 发表于2014-3-6 14:58:03 原文链接
阅读:51 评论:0 查看评论