【题解】【CF1041D】Glider

版权声明:本文为博主原创文章,需转载请联系博主。 https://blog.csdn.net/ezoixx130/article/details/82763884

题意:

一个飞行员要跳伞,他可以从任意点开始跳,从高度h开始下降,每秒向前移动一个单位,下降一个单位。

有n个区间,每个区间有左右端点l,r,飞行员经过l至r时不会下降。保证区间不相交。

给你n,h和每个区间,让你求飞行员能飞行的最远距离。

题解:

首先有一个结论:最优解一定是从某个区间的左端点起跳。

那么我们只需要判断他从每个区间的左端点起跳的飞行距离,取最大值即可。

那么预处理出每个区间之间飞行员会下降的距离的前缀和,对于每个区间,二分找出飞行员触地的位置,计算答案并更新即可。

时间复杂度:O(nlog(n))

其实容易想到O(n)的做法,因为每次触地的位置一定是递增的,直接扫描即可。
代码:(是不是很短)

#include <bits/stdc++.h>
using namespace std;

#define MAXN 200010
int n,h,ans,l[MAXN],r[MAXN],d[MAXN];

int main()
{
    scanf("%d%d",&n,&h);
    for(int i=1;i<=n;++i)scanf("%d%d",l+i,r+i),d[i]=d[i-1]+l[i]-r[i-1];
    for(int i=1;i<=n;++i)
    {
        int id=lower_bound(d+i+1,d+n+1,h+d[i])-d-1;
        ans=max(ans,r[id]-l[i]+h-d[id]+d[i]);
    }
    printf("%d\n",ans);
}

猜你喜欢

转载自blog.csdn.net/ezoixx130/article/details/82763884