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

 

你可能感兴趣的:(sequence)