Acwing 730. 机器人跳跃问题

 分析:题目要求最小值,先看看这道题是否可以用二分来做

(1)二分需满足二段性或单调性,本题中若E0满足要求,E0' >= E0是否也一定可以满足要求?

由题意可知,① 当H(k + 1) > E时,到达下一个位置的能量为 E - (H(k + 1) - E) = 2 * E - H(k + 1)

                     ② 当H(k + 1) <= E时,到达下一个位置的能量为 E + E - H(k + 1) = 2 * E - H(k + 1)

所以,所以下一个位置的能量表达式为2 * E - H(k + 1)

设E0为初始值,E1为跳到第一个位置后的能量,E2为跳到第二个位置后的能量...以此类推

若E0满足题目要求,则Ei >= 0, (i = 1, 2, 3, ....),若E0' >= E0,则Ei' >= 0

 说明Ei满足单调性,

 (2)二分进行划分的条件怎么写,若if (check(mid))成立,说明初始能量为mid时,是可以满足要求的,如果mid可以满足要求,那么所有>= mid的位置一定可以满足要求,所以将r更新为mid,否则mid不满足要求,则将l更新为mid + 1。

注意,E(i + 1) = 2 * E(i) - H(k + 1),E(i + 1)在计算时有可能会爆int,所以我们进一步优化,看中间的值达到什么程度,一定会成功

假设我们中间所有建筑物的最大高度是maxH,如果说E在某个时刻已经大于等于maxH了,证明E一定是严格递增的,因此后面的所有E,都是严格>= 0的,可以直接返回true,这样可以防止中间过程爆掉。

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 100010;

int h[N];
int n;

// 判断是否满足条件
/*
如果初始值是这个能量e的话,中间的过程e'是否都是>= 0的
(这是我们的判断条件)
我们用这个条件判断,一定可以把答案二分出来
*/
bool check(int e)
{
    for (int i = 1; i <= n; ++ i)
    {
        e = e * 2 - h[i];
        if (e >= 2e5) 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]);
    
    int l = 0, r = 1e5;
    while (l < r)
    {
        int mid = (l + r) / 2;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    
    printf("%d\n", l);
    
    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

青衫客36

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

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

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

打赏作者

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

抵扣说明:

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

余额充值