Codeforces 597B Restaurant(离散化 + 贪心)

题目链接 Restaurant

题目意思就是在n个区间内选出尽可能多的区间,使得这些区间互不相交。

我们先对这n个区间去重。

假如有两个区间[l1, r1],[l2, r2]

若满足l1 >= l2且 r1 <= r2,那么[l2, r2]就是可以被去掉的。

因为这两个区间里我们显然最多只能选择一个。

如果我们在答案里选择了[l2, r2],那么我们如果把[l2, r2]换成[l1, r1]的话

这个答案肯定还是满足题意的。

甚至可能腾出了可以放下其他区间的空间。

那么我们去重之后进行离散化,接下来就是贪心的过程。

我们把这些处理好的区间以左端点为关键字升序排序。

排好序的区间,右端点肯定也是升序的。

我们预处理出f[i]为右端点小于等于i的所有区间的编号的最大值。

我们从最后一个区间开始选,

对于当前我们可以选择的范围肯定要选择编号更大的。

因为编号越大说明左端点越大,给其他区间留出的空间越多。

于是我们从最后一个区间开始选,依次贪心,这样就可以了。

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)

typedef long long LL;

const int inf = 1e9 + 1;
const int N = 1e6 + 10;
const int A = 22;

struct node{
	int x, y, s, t;
	friend bool operator < (const node &a, const node &b){
		return a.x == b.x ? a.y < b.y : a.x < b.x;
	}
} a[N], c[N];

int b[N << 2], d[N << 2];
int cnt, tot, now;
int n, m, et;
int mx;
int st[N << 1][A];
int ans;

bool cmp(const node &a, const node &b){
	return a.s == b.s ? a.t > b.t : a.s < b.s;
}	

int main(){

	scanf("%d", &n);
	cnt = 0;
	rep(i, 1, n){
		int x, y;
		scanf("%d%d", &a[i].x, &a[i].y);
		a[i].s = a[i].y;
		a[i].t = a[i].x + inf;
	}

	sort(a + 1, a + n + 1, cmp);

	cnt = 0;
	for (int i = 1, j; i <= n;){
		j = i + 1;
		while (j <= n && a[j].t <= a[i].t) ++j;
		c[++cnt] = a[i];
		i = j;
	}

	et = 0;
	rep(i, 1, cnt){
		b[++et] = c[i].x;
		b[++et] = c[i].y;
	}

	rep(i, 1, et) d[i] = b[i];
	sort(d + 1, d + et + 1);
	tot = unique(d + 1, d + et + 1) - d - 1;
	rep(i, 1, et) b[i] = lower_bound(d + 1, d + tot + 1, b[i]) - d;
	et = 0;
	rep(i, 1, cnt){
		c[i].x = b[++et];
		c[i].y = b[++et];
	}

	mx = c[cnt].y;

	rep(i, 1, mx){
		if (i < c[1].y) continue;
		int l = 1, r = cnt;
		while (l + 1 < r){
			int mid = (l + r) >> 1;
			if (c[mid].y <= i) l = mid;
			else r = mid - 1;
		}

		if (c[r].y <= i) st[i][0] = r;
		else st[i][0] = l;

	}

	now = mx;
	ans = 0;
	for (; now > 0; ){
		int fl = st[now][0];
		if (fl == 0) break;
		++ans;
		now = c[fl].x - 1;
	}

	printf("%d\n", ans);
	return 0;

}
时间: 2024-10-16 23:23:08

Codeforces 597B Restaurant(离散化 + 贪心)的相关文章

CodeForces 597B Restaurant

简单贪心. #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> using namespace std; int n; const int maxn=500000+10; struct X { int L,R; }s[maxn]; bool cmp(const X&a,

HDU 4883 TIANKENG’s restaurant (贪心)

链接:带我学习,带我飞 第一次BC,稳挂,WA n多次,今天重新做了一下 略挫 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <map> #include <string> #include <vector> #include <set> #include <algorithm>

Codeforces Round #300——C贪心——Tourist&#39;s Notes

Description A tourist hiked along the mountain range. The hike lasted for n days, during each day the tourist noted height above the sea level. On the i-th day height was equal to some integer hi. The tourist pick smooth enough route for his hike, me

Codeforces 77C 树形dp + 贪心

题目链接:点击打开链接 题意: 给定n个点, 每个点的豆子数量 下面是一棵树 再给出起点 每走到一个点,就会把那个点的豆子吃掉一颗. 问:回到起点最多能吃掉多少颗豆子 思路:树形dp 对于当前节点u,先把子节点v都走一次. 然后再往返于(u,v) 之间,直到u点没有豆子或者v点没有豆子. dp[u] 表示u点的最大值.a[u] 是u点剩下的豆子数. #include <cstdio> #include <vector> #include <algorithm> #inc

HDU4883 TIANKENG’s restaurant 【贪心】

TIANKENG's restaurant Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 324    Accepted Submission(s): 167 Problem Description TIANKENG manages a restaurant after graduating from ZCMU, and tens

Codeforces 788A Functions again - 贪心

Something happened in Uzhlyandia again... There are riots on the streets... Famous Uzhlyandian superheroes Shean the Sheep and Stas the Giraffe were called in order to save the situation. Upon the arriving, they found that citizens are worried about

Codeforces 486C Palindrome Transformation(贪心)

题目链接:Codeforces 486C Palindrome Transformation 题目大意:给定一个字符串,长度N,指针位置P,问说最少花多少步将字符串变成回文串. 解题思路:其实只要是对称位置不相同的,那么指针肯定要先移动到这里,修改字符只需要考虑两种方向哪种更优即 可.然后将所有需要到达的位置跳出来,贪心处理. #include <cstdio> #include <cstring> #include <cstdlib> #include <vec

codeforces 735C Tennis Championship(贪心+递推)

Tennis Championship 题目链接:http://codeforces.com/problemset/problem/735/C --每天在线,欢迎留言谈论. 题目大意: 给你一个 n (2≤n≤10^18),代表一共有n位参加比赛的选手. 游戏规则: ①每次比赛,输的选手将离开赛场 ②相互比赛的选手 他们的获胜的次数相差不能超过1(获胜4次的选手只能跟3或5次的选手比赛) 问题:最终赢得比赛的选手,胜场最多能为多少. 思路: 贪心:①选一名选手让他一直获胜且优先让他参加比赛 ②当

CodeForces 545C Woodcutters (贪心orDP)

[题目链接]:click here~~ [题目大意]: 有n棵树,给出每棵树的位置和高度,然后把树砍掉,树可以向左倒也可以向右倒.输出最多能砍几棵树. [思路]:利用贪心的思想.第一棵树的左边和最后一棵树的右边没树,所以他们向两边倒,然后对于中间的树来说,首先先向左边倒,然后左边距离如果不够的话再向右边倒,向右倒的时候注意更新一下距离. 代码: /* * Problem: CodeForces 545C * Running time: 46MS * Complier: G++ * Author: