poj 2533 Longest Ordered Subsequence 最长递增子序列

作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4098562.html

题目链接:poj 2533 Longest Ordered Subsequence 最长递增子序列

使用$len[i]$表示序列中所有长度为$i$的递增子序列中最小的第$i$个数的值为$len[i]$。对于序列的第j个数$arr[j]$,在$len$中二分查找,找到最后一个小于$arr[j]$的数$len[k]$,如果$len[k]$是序列$len$中最后的一个数,那么在其尾部添加一个数$arr[j]$,否则另$len[k+1]=arr[j]$,直到遍历完$arr$。时间复杂度为O(nlogn)。

代码如下:

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <iostream>
 4 #include <cstring>
 5 #include  <vector>
 6 #define     MAXN 1010
 7 using namespace std;
 8 int arr[MAXN];
 9 int n;
10 int bs(vector<int> &arr,int num)
11 {
12     int b = 0, e = arr.size()-1;
13     int mid;
14     while( b <= e )
15     {
16         mid = (b+e)/2;
17         if( arr[mid] <= num )
18         {
19             b = mid+1;
20         }
21         else
22         {
23             e = mid-1;
24         }
25     }
26     return b;
27 }
28 int solve()
29 {
30     if( n == 0 )
31     {
32         return 0;
33     }
34     vector<int> len;
35     len.push_back(arr[0]);
36     for( int i = 1 ; i < n ; i++ )
37     {
38         if( len[len.size()-1] < arr[i])
39         {
40             len.push_back(arr[i]);
41         }
42         else
43         {
44             len[bs(len, arr[i])] = arr[i];
45         }
46     }
47     return len.size();
48 }
49 int main(int argc, char *argv[])
50 {
51     while( scanf("%d", &n) != EOF )
52     {
53         for( int i = 0 ; i < n ; i++ )
54         {
55             scanf("%d", &arr[i]);
56         }
57         printf("%d\n", solve());
58     }
59 }
View Code

同样还有一种$O(n^2)$的动态规划算法。使用$dp[i]$表示到第$i$个数最长的递增子序列的长度。每次用j从0到$i-1$遍历数组,如果发现arr[j]<arr[i],则说明其长度可以加1,最终取最大的长度作为dp[i],即:

 

\begin{equation}
dp[i] = min(dp[j])+1,(j<i,arr[j]<arr[i])
\end{equation} 

 

代码如下:

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <iostream>
 4 #include <cstring>
 5 #define     MAXN 1010
 6 using namespace std;
 7 int dp[MAXN];
 8 int arr[MAXN];
 9 int n;
10 int solve()
11 {
12     if( n == 0 )
13     {
14         return 0;
15     }
16     memset(dp, 0, sizeof(dp));
17     dp[0] = 1;
18     int res = 1;
19     for( int i = 1 ; i < n ; i++ )
20     {
21         int tmp = 0;
22         for( int j = 0 ; j < i ; j++ )
23         {
24             if( arr[i] > arr[j] )
25             {
26                 tmp = max(tmp, dp[j]);
27             }
28         }
29         dp[i] = tmp+1;
30         res = max(res, dp[i]);
31     }
32     return res;
33 }
34 int main(int argc, char *argv[])
35 {
36     while(scanf("%d", &n) != EOF)
37     {
38         for( int i = 0 ; i < n ; i++ )
39         {
40             scanf("%d", &arr[i]);
41         }
42         printf("%d\n",solve()); 
43     }
44 }
View Code

 

posted @ 2014-11-14 23:57  jostree  阅读(424)  评论(0编辑  收藏  举报