题目描述
Little Susie listens to fairy tales before bed every day. Today's fairy tale was about wood cutters and the little girl immediately started imagining the choppers cutting wood. She imagined the situation that is described below.
There are nn trees located along the road at points with coordinates x_{1},x_{2},...,x_{n}x1,x2,...,xn . Each tree has its height h_{i}hi . Woodcutters can cut down a tree and fell it to the left or to the right. After that it occupies one of the segments [x_{i}-h_{i},x_{i}][xi−hi,xi] or [x_{i};x_{i}+h_{i}][xi;xi+hi] . The tree that is not cut down occupies a single point with coordinate x_{i}xi . Woodcutters can fell a tree if the segment to be occupied by the fallen tree doesn't contain any occupied point. The woodcutters want to process as many trees as possible, so Susie wonders, what is the maximum number of trees to fell.
输入格式
The first line contains integer nn ( 1<=n<=10^{5}1<=n<=105 ) — the number of trees.
Next nn lines contain pairs of integers x_{i},h_{i}xi,hi ( 1<=x_{i},h_{i}<=10^{9}1<=xi,hi<=109 ) — the coordinate and the height of the і -th tree.
The pairs are given in the order of ascending x_{i}xi . No two trees are located at the point with the same coordinate.
输出格式
Print a single number — the maximum number of trees that you can cut down by the given rules.
题意翻译
给 n 棵树在一维数轴上的坐标,以及它们的长度。现在要你砍倒 这些树,树可以向左倒也可以向右倒,砍倒的树不能重合、当然 也不能覆盖其他的树原来的位置,现在求最大可以砍倒的树的数 目。 1 <= n <= 10^5 ; 1 <= x i , h i <= 10^9
感谢@凉凉 提供的翻译
输入输出样例
输入 #1复制
5 1 2 2 1 5 10 10 9 19 1
输出 #1复制
3
输入 #2复制
5 1 2 2 1 5 10 10 9 20 1
输出 #2复制
4
说明/提示
In the first sample you can fell the trees like that:
- fell the 11 -st tree to the left — now it occupies segment [-1;1][−1;1]
- fell the 22 -nd tree to the right — now it occupies segment [2;3][2;3]
- leave the 33 -rd tree — it occupies point 55
- leave the 44 -th tree — it occupies point 1010
- fell the 55 -th tree to the right — now it occupies segment [19;20][19;20]
In the second sample you can also fell 44 -th tree to the right, after that it will occupy segment [10;19][10;19] .
思路
题意:现在有n棵树,对应每个树都有一个位子,并且有一个对应的高度,现在我们想砍最多数量的树,使得其倒下之后,不会压倒其他的树,树可以向左倒下,也可以向右倒下。
令dp[i][0]为第i棵树向左倒的最多能砍掉的树,dp[i][1]为第i棵树向右倒的最多能砍掉的树,则:
1.不砍,第i-1树的最优状态转移到第i棵(本质上是预处理,为2,3,4情况服务)
dp[i][0]=dp[i][1]=max(dp[i-1][0],dp[i-1][1])
2.第i棵向左倒,第i-1棵也向左倒
当a[i].position-a[i].height>a[i-1].position时
dp[i][0]=max(dp[i][0],dp[i-1][0]+1)
不砍或砍。
3.第i棵向左倒,第i-1棵向右倒
当a[i].position-a[i].height>a[i-1].position+a[i-1].height时
dp[i][0]=max(dp[i][0],dp[i-1][1]+1)
不砍或砍。
4.第i棵向右倒
当a[i].position+a[i].height<a[i+1].position时
dp[i][1]=dp[i][1]+1
答案为max(dp[n][0],dp[n][1])。
#include <stdio.h>
#include <iostream>
#define N 100001
#define inf 2e9+7
using namespace std;
struct node
{
int position,height;
}a[N];
int dp[N][2],n,s;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
register int i,j;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>a[i].position>>a[i].height;
}
a[n+1].height=inf;
a[n+1].position=inf;
a[0].height=-inf;
for(i=1;i<=n;i++)
{
dp[i][1]=dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
if(a[i].position-a[i].height>a[i-1].position)
{
dp[i][0]=max(dp[i][0],dp[i-1][0]+1);
}
if(a[i].position-a[i].height>a[i-1].position+a[i-1].height)
{
dp[i][0]=max(dp[i][0],dp[i-1][1]+1);
}
if(a[i].position+a[i].height<a[i+1].position)
{
dp[i][1]++;
}
}
cout<<max(dp[n][0],dp[n][1])<<endl;
return 0;
}