ASC(1)--G(DP,双LIS)

2014-11-09 17:22:51

思路:这题简而言之就是给你N个数对,每个数对有两个数s和b,让你求最长的使得s和b都严格上升的数列。

   首先将s升序排序,s相同的情况将b降序排序,这样就是直接在剩下的b数列中求LIS了(因为s升,b降这样排的话不会使最后的序列里b对应的s相等,思考)

 1 /*************************************************************************
 2     > File Name: b.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com
 5     > Created Time: Sun 09 Nov 2014 05:04:05 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 
27 int N;
28 int que[100010],len;
29 int path[100010];
30 int pre[100010];
31 
32 struct node{
33     int s,b,id;
34 }t[100010];
35 
36 bool cmp(node a,node b){
37     if(a.s == b.s)
38         return a.b > b.b;
39     return a.s < b.s;
40 }
41 
42 int B_search(int val){
43     int l = 1,r = len + 1;
44     while(l < r){
45         int mid = getmid(l,r);
46         if(que[mid] >= val)
47             r = mid;
48         else
49             l = mid + 1;
50     }
51     return l;
52 }
53 
54 void Print(int p){
55     if(pre[p] != -1)
56         Print(pre[p]);
57     if(pre[p] != -1) printf(" ");
58     printf("%d",p);
59 }
60 
61 int main(){
62     scanf("%d",&N);
63     for(int i = 1; i <= N; ++i){
64         scanf("%d%d",&t[i].s,&t[i].b);
65         t[i].id = i;
66     }
67     sort(t + 1,t + N + 1,cmp);
68     path[0] = -1;
69     for(int i = 1; i <= N; ++i){
70         int pos = B_search(t[i].b);
71         if(que[pos] == t[i].b)
72             continue;
73         que[pos] = t[i].b;
74         path[pos] = t[i].id;
75         pre[t[i].id] = path[pos - 1];
76         if(pos > len)
77             ++len;
78     }
79     printf("%d\n",len);
80     Print(path[len]);
81     printf("\n");
82     return 0;
83 }

 

posted @ 2014-11-09 17:41  Naturain  阅读(158)  评论(0编辑  收藏  举报