HDU 1160 排序或者通过最短路两种方法解决

题目大意:

给定一堆点,具有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 }

 

你可能感兴趣的:(HDU)