题目链接
https://codeforces.com/problemset/problem/545/C
题目描述
给 n 棵树在一维数轴上的坐标,以及它们的长度。现在要你砍倒 这些树,树可以向左倒也可以向右倒,砍倒的树不能重合、当然 也不能覆盖其他的树原来的位置,现在求最大可以砍倒的树的数 目。 1 <= n <= 10^5 ; 1 <= x i , h i <= 10^9
解题思路
根据题意的样例解释我们可以得知,将树向左倒或向右倒会形成的一个区间,就是求数量最多并不重叠的区间。在学习贪心算法时,大部分同学应该做过《活动选择》这道题,即每次都选择最早结束的那个活动,这道题的解决思路也是一样的。但是这道题要求砍倒的树不能覆盖前一棵树或后一棵树,因此我们连排序都省了。
参考代码
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 100005;
struct Seg{
int x,h;
Seg(){ x = h = 0;}
Seg(int X, int H){
x = X;
h = H;
}
} seg[ MAXN];
int n;
int seg_num;
int main(){
int x,h;
scanf("%d",&n);
for(int i = 1; i <= n; i++){
scanf("%d%d",&x,&h);
seg[i] = Seg( x,h );
}
int t = -1000000009;
int ans = 0;
seg[0].x = -1000000007;
seg[n+1].x = 2000000009;
for(int i = 1; i <= n; i++){
//向左倒
int w = seg[i].x - seg[i].h;
if( w > t && w > seg[i-1].x ) {
ans++;
t = seg[i].x;
continue;
}
//向右倒
w = seg[i].x + seg[i].h;
if( w > t && w < seg[i+1].x) {
ans++;
t = w;
}
}
printf("%d\n",ans);
return 0;
}