砍树问题
题目链接:ybt高效进阶强化训练1-2-2
题目大意
一行上有 n 个树,有高度,然后问你至少要砍去多少高度的树,才使得任意一个树,它不会挡住任意其它树。
一个树 a 会挡住另一个树 b,要 a 顶端和 b 底端连线的倾角大于 45 度。
思路
首先不难发现一个东西,就是如果
a
,
b
,
c
a,b,c
a,b,c 三个数从左到右,如果
a
a
a 挡住
c
c
c,那它一定会挡住
b
b
b。
而且如果
a
a
a 不挡住
b
b
b,它一定不会挡住
c
c
c。
那我们就只需要按位置排序,然后只考虑它两边的相邻树即可。
然后就可以确定出树最高可以的高度,然后去减现在的高度就是它要砍掉的高度了。
(记得要对
0
0
0 取最大值表示不用干)
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int p, a;
}a[100001];
int n, ans;
bool cmp(node x, node y) {
return x.p < y.p;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d %d", &a[i].p, &a[i].a);
sort(a + 1, a + n + 1, cmp);
for (int i = 1; i <= n; i++) {
int h = 1e9;//看两边选高度
if (i != 1) h = min(h, a[i].p - a[i - 1].p);
if (i != n) h = min(h, a[i + 1].p - a[i].p);
ans += max(0, a[i].a - h);
}
printf("%d", ans);
return 0;
}