题目大意:

给定一堆点,具有x,y两个值

找到一组最多的序列,保证点由前到后,x严格上升,y严格下降,并把最大的数目和这一组根据点的编号输出来

 

这里用两种方法来求解:

1.

我们可以一开始就将数组根据x由大到小排个序,由前往后取,保证x严格上升了

只要每次取得过程中找一条x不相等的关于y的最长下降子序列即可,加个回溯,输出所有点

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 
 5 using namespace std;
 6 const int N = 1005;
 7 int dp[N] , fa[N] , rec[N];
 8 
 9 struct Node{
10     int x , y , id;
11     bool operator<(const Node &m)const{
12         if(x == m.x) return y < m.y;
13         return x < m.x;
14     }
15 }node[N];
16 
17 int main()
18 {
19     //freopen("a.in" , "r" , stdin);
20     int k = 0;
21     while(scanf("%d%d" , &node[k].x , &node[k].y) != EOF){
22         node[k].id = k + 1;
23         k++;
24     }
25     //先保证都是以x由小到大排列
26     sort(node , node+k);
27 
28     memset(dp , 0 , sizeof(dp));
29     memset(fa , -1 , sizeof(fa));
30     dp[0] = 1;
31     //x已满足上升,现在处理y使其按下降顺序排列即可,按照最长上升子序列的O(n^2)的方法类似处理即可
32     for(int i = 1 ; i<k ; i++){
33         dp[i] = 1;
34         for(int j = 0 ; j<i ; j++){
35             if(node[j].x != node[i].x && node[i].y < node[j].y){
36                 if(dp[i] < dp[j] + 1){
37                     dp[i] = dp[j] + 1;
38                     fa[i] = j;
39                 }
40             }
41         }
42     }
43 
44     int maxn = 0 , la;
45     for(int i = 0 ; i<k ; i++){
46         if(maxn < dp[i]) maxn = dp[i] , la = i;
47     }
48 
49     int cnt = 0;
50     rec[cnt++] = la;
51     while(fa[la] >= 0){
52         rec[cnt++] = fa[la];
53         la = fa[la];
54     }
55     printf("%d\n" , maxn);
56     for(int i =cnt-1 ;  i>=0 ; i--)
57         printf("%d\n" , node[rec[i]].id);
58 
59     return 0;
60 }

2.

我们对所有m1.x<m2.x , m1.y>m2.y的m1和m2间添加一条有向线段

这样我们可以从所有入度为0的点出发,进行bfs,每一条边认为长度为1,入度为0的点认为dp[i] = 1表示到达第i个点最多能有多少个物品

计算最短路径的过程加个回溯这个题目就解决了

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <queue>
  5 #include <iostream>
  6 using namespace std;
  7 const int N = 1005;
  8 int dp[N] , fa[N] , rec[N] , k , t , first[N];
  9 int in[N] , vis[N];
 10 queue<int> q;
 11 
 12 struct Node{
 13     int x , y , id;
 14     bool operator<(const Node &m)const{
 15         if(x == m.x) return y < m.y;
 16         return x < m.x;
 17     }
 18 }node[N];
 19 
 20 struct Edge{
 21     int y , next;
 22 }e[N*N];
 23 
 24 void add_edge(int x, int y)
 25 {
 26     e[k].y = y , e[k].next = first[x];
 27     first[x] = k++;
 28 }
 29 
 30 void bfs(int s)
 31 {
 32     memset(vis , 0 , sizeof(vis));
 33     q.push(s);
 34     vis[s] = 1;
 35     while(!q.empty()){
 36         int u = q.front();
 37         q.pop();
 38         vis[u] = 0;
 39         for(int i = first[u] ; i!=-1 ; i = e[i].next){
 40             int v = e[i].y;
 41             if(dp[v] < dp[u] + 1){
 42                 dp[v] = dp[u] + 1;
 43                 fa[v] = u;
 44                 if(!vis[v]){
 45                     vis[v] = 1;
 46                     q.push(v);
 47                 }
 48             }
 49         }
 50     }
 51 }
 52 
 53 bool ok(int ith1 , int ith2)
 54 {
 55     return node[ith1].x < node[ith2].x && node[ith1].y > node[ith2].y;
 56 }
 57 
 58 int main()
 59 {
 60    // freopen("a.in" , "r" , stdin);
 61     t = 1 , k = 0;
 62     memset(first , -1 , sizeof(first));
 63     memset(dp , 0 , sizeof(dp));
 64     memset(in , 0 , sizeof(in));
 65     while(scanf("%d%d" , &node[t].x , &node[t].y) != EOF){
 66         node[t].id = t + 1;
 67         t++;
 68     }
 69 
 70     for(int i = 1 ; i<t ; i++){
 71         for(int j = 1 ; j<i ; j++){
 72             if(ok(i , j)){
 73                 add_edge(i , j);
 74                 in[j] ++;
 75             }
 76             if(ok(j , i)){
 77                 add_edge(j , i);
 78                 in[i] ++;
 79             }
 80         }
 81     }
 82 
 83     for(int i = 1 ; i<t ; i++)
 84         if(in[i] == 0){
 85             dp[i] = 1;
 86             bfs(i);
 87         }
 88 
 89     int maxn = 0 , la;
 90     for(int i = 1 ; i<t ; i++){
 91         if(maxn < dp[i]){
 92             maxn = max(maxn , dp[i]);
 93             la = i;
 94         }
 95     }
 96 
 97     int cnt = 0;
 98     rec[cnt++] = la;
 99     while(fa[la]){
100         rec[cnt++] = fa[la];
101         la = fa[la];
102     }
103     printf("%d\n" , maxn);
104     for(int i = cnt-1 ; i>=0 ; i--)
105         printf("%d\n" , rec[i]);
106 
107     return 0;
108 }

 

 posted on 2014-12-24 21:53  Love风吟  阅读(188)  评论(0编辑  收藏  举报