题目链接https://csustacm.fun/problem/1019
Description
小明喜欢看直播,他订阅了很多主播,主播们有固定的直播时间 [Li, Ri] 。
可是他网速只有2M,不能同时播放两个直播,所以同一时间只能看一个直播。
并且他只会去看能完整看完的直播(从开播到停播都能观看)。
他想知道最多能看多长时间的直播呢?
注意 [1, 3] 和 [3, 4] 不能两者都选择。
Input
第一行一个N。
接下来N行每行两个整数Li, Ri。
1 <= N <= 2e5
1 <= Li <= Ri <= 1e9
Output
输出最多能看的时间。
Sample Input 1
3
1 3
2 6
5 8
Sample Output 1
7
受到之前做过二分+单调栈的影响。。。这题也就很自然的想出来了。。
我们可以用类似于背包的方式来做,即计算一下扣去本段能获得的时间比上不扣的时间,那么怎么才能知道本段时间影响了多少个段呢?排序+二分就好了,我们按照右端点排序,那么本段能够影响的就是的右端点大于本段左端点的段。于是我们就可以愉快地dp啦
以下是AC代码:
#include <bits/stdc++.h>
using namespace std;
const int mac = 2e5 + 10;
#define ll long long
struct node
{
int l, r;
bool operator<(const node& a)const {
return r < a.r;
}
};
node a[mac];
ll dp[mac];
int b[mac];
int read();
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
a[i].l = read(); a[i].r = read();
}
sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; i++) b[i] = a[i].r;
dp[1] = a[1].r - a[1].l + 1;
ll ans = dp[1];
for (int i = 2; i <= n; i++) {
int it = lower_bound(b + 1, b + 1 + i, a[i].l) - b;
if (it <= 0) dp[i] = dp[i - 1];
else dp[i] = max(dp[i - 1], dp[it-1] + a[i].r - a[i].l + 1);
ans = max(ans, dp[i]);
}
printf("%lld\n", ans);
return 0;
}
int read()
{
char ch = getchar();
int x = 0;
while (ch > '9' || ch < '0') ch = getchar();
while (ch >= '0' && ch <= '9') {
x = (x<<3)+(x<<1)+ch-'0';
ch = getchar();
}
return x;
}