HDU 1025 最长上升子序列

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

这里要用到最长上升子序列的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 }
时间: 2024-10-24 10:06:22

HDU 1025 最长上升子序列的相关文章

hdu 1950 最长上升子序列

1 //Accepted 3540 KB 62 ms 2 //dp 最长上升子序列 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 using namespace std; 7 const int imax_n = 400005; 8 int dp[imax_n]; 9 int d[imax_n]; 10 int a[imax_n]; 11 int n; 12 int len; 13 in

HDU 1243 最长公共子序列

反恐训练营 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2850    Accepted Submission(s): 648 Problem Description 当今国际反恐形势很严峻,特别是美国“9.11事件”以后,国际恐怖势力更是有恃无恐,制造了多起骇人听闻的恐怖事件.基于此,各国都十分担心恐怖势力会对本国社会造成的不稳定,

NYOJ 36 &amp;&amp;HDU 1159 最长公共子序列(经典)

链接:click here 题意:tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列. 输入 第一行给出一个整数N(0<N<100)表示待测数据组数 接下来每组数据两行,分别为待测的两组字符串.每个字符串长度不大于1000. 输出 每组测试数据输出一个整数,表示最长公共子序列长度.每组

HDU 5784 最长上升子序列的长度nlgn(固定尾部)

Bellovin Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 858    Accepted Submission(s): 395 Problem Description Peter has a sequence a1,a2,...,an and he define a function on the sequence -- F(

hdu 5773 最长递增子序列 (nlogn)+贪心

The All-purpose Zero Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 947    Accepted Submission(s): 453 Problem Description ?? gets an sequence S with n intergers(0 < n <= 100000,0<= S[i] &l

HDU 1159 最长公共子序列(n*m)

Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 32693    Accepted Submission(s): 14786 Problem Description A subsequence of a given sequence is the given sequence with some el

HDU 5773 最长上升子序列

题意 给出一个序列 问它的最长严格上升子序列多长 这个序列中的0可以被替代为任何数 n的范围给出了1e5 所以平常的O(n*n)lis不能用了 在kuangbin的模板里有O(nlogn)的模板 套上就可以过了 但是比赛的时候没有拿模板= =. 于是就想出了另外一个时间复杂度不明的办法= =. 将序列从前往后扫 设定一个数组a a[i]=z a[i]为当前i长度的上升子序列中的最小的尾数的大小 maxl为当前找出的最长的子序列长度 每次我们扫到一个数 都对0-maxl长度的a[i]进行判断 看能

HDU 1159 最长公共子序列

Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 53443    Accepted Submission(s): 24607 Problem Description A subsequence of a given sequence is the given sequence with some el

hdu 5747 最长上升子序列 (nlogn)

ac code: #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; #define INF 1e9 #define maxn 100005 int a[maxn]; //记录原序列 int d[maxn]; //d[k] 表示长度为k的上升子序列结尾的最小值 int f