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

HDU 1025 最长上升子序列

时间:2014-12-16 00:45:29      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   ar   color   os   sp   for   on   

首先根据第一个数排序,然后可以得到一串第二个数组成的序列,因为第一个由大到小排列,所以第二组中取到的数据,后面的不能比前面的小才不会形成交叉,那么也就是求这个新序列的最长公共子序列

这里要用到最长上升子序列的nlogn的算法,新建一个数组保存所有合理的数据的数组g,比如g数组中有了1,4,6,加进来一个3 , 那么4可以被3代替因为在同一个位置尽可能小能容纳的数据个数就会越多,越能找到更长的序列,这个找位置的过程就用二分搜索logn的复杂度

注意一点,我是因为这个好久没做出。。。。就是边数大于1的时候road会变为复数roads

 另外这是看的别人的直接写在main函数中的二分,觉得比我的简便很多

ans[1]=num[1];
  len=1;
  for(i=2;i<=n;i++)
  {
   /*****/                   //这个二分是别人写的,表示比我写的好多了- -I。
   low=1;
   up=len;
   while(low<=up)
   {
    mid=(low+up)/2;
    if(ans[mid]<num[i]) low=mid+1;
    else up=mid-1;
   }
   ans[low]=num[i];
   if(low>len) len++;
   /*****/
  }

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 using namespace std;
 6 
 7 const int maxn = 500005;
 8 int num[maxn] , g[maxn]; //g数组存一个顺序序列
 9 
10 struct Pair{
11     int x , y;
12     bool operator<(const Pair &m)const{
13         return x < m.x;
14     }
15 }p[maxn];
16 
17 int bin_search(int m , int k)
18 {
19     int st = 0 , la = k , ans = 0;
20     int mid;
21     while(st <= la){
22         mid = (st + la) / 2;
23         if( m > g[mid] && m <= g[mid + 1]){
24             ans = mid + 1;
25             break;
26         }
27         else if(m <= g[mid]) la = mid - 1;
28         else st = mid + 1;
29     }
30     return ans;
31 }
32 
33 int main()
34 {
35    // freopen("a.in" , "r" , stdin);
36     int n , cas = 0;
37     while(scanf("%d" , &n) != EOF){
38         for(int i = 0 ; i<n ; i++){
39             scanf("%d%d" , &p[i].x , &p[i].y);
40         }
41         sort(p , p+n);
42 
43         for(int i = 0 ; i<n ; i++)
44             num[i+1] = p[i].y;
45 
46         int k = 0;
47         g[0] = 0;
48         for(int i = 1 ; i<=n ; i++){
49             if(num[i] > g[k]) g[++k] = num[i];
50             else{
51                 int pos = bin_search(num[i] , k);
52                 g[pos] = num[i];
53             }
54         }
55         //这里不止一条路的话是复数roads!!!
56         if(k == 1) printf("Case %d:\nMy king, at most %d road can be built.\n" , ++cas , k);
57         else printf("Case %d:\nMy king, at most %d roads can be built.\n" , ++cas , k);
58         puts("");
59     }
60     return 0;
61 }

 

HDU 1025 最长上升子序列

标签:style   blog   io   ar   color   os   sp   for   on   

原文地址:http://www.cnblogs.com/CSU3901130321/p/4166148.html

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