看直播--CSUSTOJ-1019(dp+二分)

题目链接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 
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;
}

 

你可能感兴趣的:(#,csust2017区域个人,#,基础DP,#,二分&三分)