机器人跳跃问题

机器人跳跃问题

题目描述

C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210318180145762.png


题意解释

在这里插入图片描述


核心思路

根据题意可知:

  • H ( k + 1 ) > E H(k+1)>E H(k+1)>E时,则要损失 H ( k + 1 ) − E H(k+1)-E H(k+1)E的能量,那么此时的能量为 E − ( H ( k − 1 ) − E ) = 2 E − H ( k + 1 ) E-(H(k-1)-E)=2E-H(k+1) E(H(k1)E)=2EH(k+1)
  • H ( k + 1 ) ≤ E H(k+1)\leq E H(k+1)E时,则要得到 E − H ( k + 1 ) E-H(k+1) EH(k+1)的能量,那么此时的能量为 E + ( E − H ( k + 1 ) ) = 2 E − H ( k + 1 ) E+(E-H(k+1))=2E-H(k+1) E+(EH(k+1))=2EH(k+1)

于是我们发现这两种情况都会得到相同的值 2 E − H ( k + 1 ) 2E-H(k+1) 2EH(k+1)

问题:假设我们找到了某个初始能量 E 0 E_0 E0是满足要求的。然后已知 E 0 ′ > E 0 E_0'>E_0 E0>E0,那么初始能量 E 0 ′ E_0' E0是否也满足要求呢?

答案是肯定的。证明如下: 假设有3个建筑。公式 2 E − H [ k + 1 ] 2E-H[k+1] 2EH[k+1]

对于初始能量 E 0 E_0 E0来说,第一个建筑的能量为 E 1 = 2 E 0 − H [ 1 ] E_1=2E_0-H[1] E1=2E0H[1],第二个建筑的能量为 E 2 = 2 E 1 − H [ 2 ] E_2=2E_1-H[2] E2=2E1H[2],第三个建筑的能量为 E 3 = 2 E 2 − H [ 3 ] E_3=2E_2-H[3] E3=2E2H[3]

对于初始能量 E 0 ′ E_0' E0来说,第一个建筑的能量为 E 1 ′ = 2 E 0 ′ − H [ 1 ] E_1'=2E_0'-H[1] E1=2E0H[1],第二个建筑的能量为 E 2 ′ = 2 E 1 ′ − H [ 2 ] E_2'=2E_1'-H[2] E2=2E1H[2],第三个建筑的能量为 E 3 ′ = 2 E 2 ′ − H [ 3 ] E_3'=2E_2'-H[3] E3=2E2H[3]。因为 E 0 ′ > E 0 E_0'>E_0 E0>E0,因此有 E 1 ′ > E 1 E_1'>E_1 E1>E1,于是有 E 2 ′ > E 2 E_2'>E_2 E2>E2,接着有 E 3 ′ > E 3 E_3'>E_3 E3>E3。运用数学归纳法可知, E i ′ > E i E_i'>E_i Ei>Ei ⋯ \cdots E n ′ > E n E_n'>E_n En>En

因此,证明了只要找到某个初始能量 E 0 E_0 E0是满足要求的,那么所有大于等于 E 0 E_0 E0的能量也是满足要求的。

这样,我们就知道了它是有单调性的,即 ≥ E 0 \geq E_0 E0都满足, < E 0 <E_0 <E0都不满足。只要具有了单调性,就一定可以用二分算法来做。但是能用二分法来做并不一定需要具有单调性,二分算法的本质是二段性而不是单调性。

在这里插入图片描述

设这些建筑中最大的高度为 M a x H MaxH MaxH M a x H > 0 MaxH>0 MaxH>0,设某一时刻的能量 E i ≥ M a x H E_i\geq MaxH EiMaxH E i > 0 E_i>0 Ei>0,那么下一个能量 E i + 1 = 2 E i − h [ i + 1 ] E_{i+1}=2E_i-h[i+1] Ei+1=2Eih[i+1],即 E i + 1 = E i + E i − h [ i + 1 ] ≥ E i + ( M a x H − h [ i + 1 ] ) E_{i+1}=E_i+E_i-h[i+1]\geq E_i+(MaxH-h[i+1]) Ei+1=Ei+Eih[i+1]Ei+(MaxHh[i+1]),由于 M a x H ≥ h [ i + 1 ] MaxH\geq h[i+1] MaxHh[i+1],所以 M a x H − h [ i + 1 ] ≥ 0 MaxH-h[i+1]\geq 0 MaxHh[i+1]0,也就有 E i + 1 ≥ E i E_{i+1}\geq E_i Ei+1Ei,而 E i > 0 E_i>0 Ei>0,所以有 E i + 1 > 0 E_{i+1}>0 Ei+1>0,也就是 E i + 1 − E i ≥ 0 E_{i+1}-E_i\geq 0 Ei+1Ei0,也就是说,当出现 E = = M a x H E==MaxH E==MaxH了,那么后面的能量就都是递增的了,而不会是递减。既然能保证后面的能量是>0的,而不是负数,那么就是满足题目要求的,那么也就没有必要去算 E E E后面的了。之所以这么想,就是因为 2 ∗ E − h 2*E-h 2Eh,由于是相乘,如果 h h h很小,那么可能由于相乘的结果很大而爆long long。因此,我们需要作出这种优化来规避爆long long。

问题:如何理解二分的右范围是1e5呢?

题目说了建筑物最大是1e5。由上面我们证明了,当某个时刻 E = = M a x H E==MaxH E==MaxH后,能量就是递增的,后面的一定都是答案,但是在还没有碰到 E = = M a x H E==MaxH E==MaxH前,有可能会出现答案。也就是说很不幸的是,有个建筑物的高度是1e5,然后只有当 E = 1 e 5 E=1e5 E=1e5时,我们才能保证1e5以上的都是答案,我们肯定知道1e5以上的都是答案了,因此1e5以上的就没有必要去二分了。由于是求最小的初始能量,所以只需要在区间 [ 1 , 1 e 5 ] [1,1e5] [1,1e5]之间找就行了。而且这个区间中的答案一定比1e5以上区间的答案还要是最优解。(因为有单调性)


代码

#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int n;
int h[N];   //存储所有建筑物的高度
int maxH=0; //记录这些建筑物中的最大的那个高度
//判断某个点e是否满足 "大于等于E0" 的这个性质
bool check(int e)
{
    for(int i=1;i<=n;i++)
    {
        //公式
        e=e*2-h[i];
        //当某一个时刻出现e>=maxH,则后面的所有能量就都是满足要求的,都是答案
        if(e>=maxH)
            return true;
        //出现能量是负数,则不符合要求
        if(e<0)
            return false;
    }
    return true;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&h[i]);
        maxH=max(maxH,h[i]);
    }
    //所需的最少的初始能量的范围是[1,1e5]   1e5以上的肯定都是答案,但不是最小的
    int l=0,r=1e5;
    //二分找到 大于等于某个东西的最小值  即最大值的最小 即左侧边界
    //由于证明了有单调性,那么一定可以用二分
    while(l<r)
    {
        int mid=l+r>>1;
        if(check(mid))
            r=mid;
        else
            l=mid+1;
    }
    //退出while循环后的l和r就是答案
    printf("%lld\n",l);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卷心菜不卷Iris

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值