码迷,mamicode.com
首页 > 其他好文 > 详细

sicily LIS

时间:2015-03-29 12:15:33      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

http://soj.sysu.edu.cn/show_problem.php?pid=1000&cid=1762

这题的n达到了1000000,n^2的最长递增子序列做法肯定超时,于是有一种二分的算法,与此题完美地结合起来!达到nlogn的时间复杂度!

 1 /*
 2 最长递增子序列+二分查找 
 3 因为在获得最长递增子序列的时候,dp数组是有序的,所以把数加进去的时候,就合理地可以用二分啦! 
 4  
 5 a:  1 7 3 5 9 4 8 
 6 dp: 0 0 0 0 0 0 0 0
 7 
 8 a:  1 7 3 5 9 4 8 
 9 dp: 0 1 0 0 0 0 0 0 (初始化:dp[1] = a[0],下标从1开始,代表最长递增子序列的长度)
10 
11 a:  1 7 3 5 9 4 8 
12 dp: 0 1 7 0 0 0 0 0 (7找不到比他小的,补在后面)
13 
14 a:  1 7 3 5 9 4 8 
15 dp: 0 1 3 0 0 0 0 0 (3找到7且小于它,替换之)
16 
17 ......到最后......
18 
19 a:  1 7 3 5 9 4 8 
20 dp: 0 1 3 4 8 0 0 0 (此时长度为4,最后刚好是8)
21 
22 */
23 
24 #include <iostream>
25 #include <cstring>
26 #include <cstdio>
27 
28 using namespace std;
29 
30 int a[1000005];
31 int dp[1000005];
32 
33 int binary_search(int l, int r, int key)
34 {
35     if(dp[r] <= key)
36         return r+1;
37     while(l < r) //不能等于啊 
38     {
39         int mid = (l + r) / 2;
40         if(dp[mid] <= key)
41             l = mid + 1;
42         else
43             r = mid;
44     }
45     return l;
46 }
47 
48 int LIS(int n)
49 {
50     memset(dp, 0, sizeof(dp));
51     int len = 1;
52     dp[1] = a[0];
53     for(int i=1; i<n; i++)
54     {
55         int pos = binary_search(1, len, a[i]);
56         dp[pos] = a[i];
57         if(len < pos)
58             len = pos;
59     }
60     return len;
61 }
62 
63 int main()
64 {
65     int n;
66     while(scanf("%d", &n) != EOF)
67     {
68         for(int i=0; i<n; i++)
69             scanf("%d", &a[i]);    
70         int len = LIS(n);
71         printf("%d ", len);        
72         printf("%d\n", dp[len]);
73     }
74     return 0;
75 }

 

sicily LIS

标签:

原文地址:http://www.cnblogs.com/dominjune/p/4375474.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!