URAL 1078. Segments(记录路径的简单dp)

18 篇文章 0 订阅

题目意思是给你n条线段让你求出有多少线段是覆盖的。按右边与左边排一下序,然后就是一个“求最长上升序列”了啊。然后要打印路径,打印路径想麻烦了啊、、wa了啊几次、、sad啊、、

ps:special judge。

078. Segments

Time limit: 1.0 second
Memory limit: 64 MB
A number of segments are lying on a line. Every segment is given with the coordinates of its endpoints. Segments are numbered from 1 to  N (0 <  N < 500). We assume, that one segment is inside another, if the two segments are different, the first one is fully contained in the second one, and their endpoints do not coincide. Write a program, which finds the numbers of the segments in the longest sequence of segments which are contained in. In the sequence, every segment except the last is inside the next segment in the sequence.

Input

The first line contains one integer  N. Next, there are  N lines, with two integers on every line, which are the coordinates of the left and the right endpoints of the corresponding segment. These coordinates are integers in the interval [–10000, 10000]. We assume that, the given segments are numbered according to their place in the input.

Output

The first line must contain one integer, equal to the number of segments in the found sequence. The following line must contain the numbers of the segments in this sequence. These numbers must be outputted, in the order in which the segments' lengths increase, starting from the smallest. If there are more than one output sequences, write any of them.

Sample

input output
4
-2 2
-1 1
-3 3
4 5
3
2 1 3

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-7
#define M 1000100
#define LL __int64
//#define LL long long
#define INF 0x3fffffff
#define PI 3.1415926535898

using namespace std;

const int maxn = 510;

struct node
{
    int l, r;
    int num;
} f[maxn];

int dp[maxn];
int pre[maxn];
int ff[maxn];

bool cmp(node a, node b)
{
    if(a.r == b.r)
        return a.l < b.l;
    return a.r < b.r;
}

int main()
{
    int n;
    while(cin >>n)
    {
        for(int i = 1; i <= n; i++)
        {
            cin >>f[i].l>>f[i].r;
            f[i].num = i;
        }
        sort(f+1, f+n+1, cmp);
        memset(pre, -1, sizeof(pre));
        for(int i = 1; i <= n; i++)
            dp[i] = 1;
        for(int i = 2; i <= n; i++)
        {
            for(int j = i-1; j >= 1; j--)
            {
                if(f[i].r > f[j].r && f[i].l < f[j].l)
                {
                    if(dp[i] < dp[j]+1)
                    {
                        dp[i] = dp[j]+1;
                        pre[i] = j;
                    }
                }
            }
        }
        int Max = -1;
        int p;
        for(int i = 1; i <= n; i++)
        {
            if(dp[i] > Max)
            {
                Max = dp[i];
                p = i;
            }
        }
        cout<<Max<<endl;
        int t = 0;
        int s = p;
        while(s != -1)
        {
            ff[t++] = s;
            s = pre[s];
        }
        for(int i = t-1; i > 0; i--)
            cout<<f[ff[i]].num<<" ";
        cout<<f[ff[0]].num<<endl;
    }
    return 0;
}
/*
Test case 2:
9
-1 1
-2 2
-3 3
-10 10
3 6
4 5
2 7
1 8
0 9
Answer:
6
6 5 7 8 9 4

Test case 3:
100
272 422
352 367
102 435
274 469
532 554
88 468
28 761
334 381
62 236
858 955
104 930
4 892
467 749
39 695
189 709
217 790
571 999
126 355
138 779
570 645
31 222
372 511
345 888
535 731
435 953
87 869
172 863
442 936
450 704
452 697
862 896
887 977
510 844
135 225
95 932
632 888
30 704
165 523
47 306
107 645
22 34
237 712
779 796
505 964
419 495
171 751
449 616
62 642
355 954
101 266
71 585
284 723
69 900
781 998
21 338
619 950
173 239
394 502
183 605
113 999
30 748
122 833
541 829
65 453
650 741
141 562
355 928
360 852
83 997
563 590
482 668
318 980
84 170
233 858
9 484
637 799
104 611
483 856
29 889
16 463
530 709
774 979
414 654
332 527
406 476
257 735
57 257
201 508
259 806
62 955
410 790
37 720
490 893
573 779
241 400
315 640
242 940
165 929
54 814
356 501
Answer:
13
2 8 95 88 38 66 77 48 14 92 61 79 12
*/


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值