洛谷题单【算法1-5】贪心——P1803 凌乱的yyy / 线段覆盖

177 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情

P1803 凌乱的yyy / 线段覆盖

题目背景

快 noip 了,yyy 很紧张!

题目描述

现在各大 oj 上有 nn 个比赛,每个比赛的开始、结束的时间点是知道的。

yyy 认为,参加越多的比赛,noip 就能考的越好(假的)。

所以,他想知道他最多能参加几个比赛。

由于 yyy 是蒟蒻,如果要参加一个比赛必须善始善终,而且不能同时参加 22 个及以上的比赛。

输入格式

第一行是一个整数 nn ,接下来 nn 行每行是 22 个整数 ai,bia_{i},b_{i} ( ai<bia_{i}<b_{i} ),表示比赛开始、结束的时间。

输出格式

一个整数最多参加的比赛数目。

样例 #1

样例输入 #1

3
0 2
2 4
1 3

样例输出 #1

2

提示

对于 20%20\% 的数据, n10n \le 10

对于 50%50\% 的数据, n103n \le 10^3

对于 70%70\% 的数据, n105n \le 10^{5}

对于 100%100\% 的数据, 1n1061\le n \le 10^{6}0ai<bi1060 \le a_{i} < b_{i} \le 10^6

思路

用结构体保存所有线段的起始位置和结束位置

然后以右端点的位置排序所有线段

从前往后不断的排线段就可以了

代码

// P1803 凌乱的yyy / 线段覆盖

#include <bits/stdc++.h>
using namespace std;

struct line{
    int left;
    int right;
    int use;
}l[1000010];

int cnt = 0;
int n;

void find(int head){
    for(int i=0; i<n; i++){
        if(l[i].left >= head && l[i].use == 0){
            l[i].use = 1;
            cnt++;
            find(l[i].right);
            break;//TLE后加的代码,找到的递归情况一定是最佳,无序再找,直接跳出
        }
    }
    return;
}

bool cmp(line a, line b){
    return a.right < b.right;
}

int main(int argc, char const *argv[])
{
    cin >> n;
    for(int i=0; i<n; i++){
        cin >> l[i].left >> l[i].right;
        l[i].use = 0;
    }
    sort(l, l+n, cmp);
    find(0);
    cout << cnt;
    return 0;
}