题目描述
游戏中有N+1座建筑——从0到N编号,从左到右排列。编号为0的建筑高度为0个单位,编号为i的建筑的高度为Hi个单位。
起初, 机器人在编号为0的建筑处。每一步,它跳到下一个(右边)建筑。假设机器人在第k个建筑,且它现在的能量值是E, 下一步它将跳到第个k+1建筑。它将会得到或者失去正比于与Hk+1与E之差的能量。如果Hk+1> E 那么机器人就失去Hk+1- E 的能量值,否则它将得到 E - Hk+1的能量值。
游戏目标是到达第个N建筑,在这个过程中,能量值不能为负数个单位。现在的问题是机器人以多少能量值开始游戏,才可以保证成功完成游戏?
输入描述:
第一行输入,表示一共有 N 组数据.
第二个是 N 个空格分隔的整数,H1, H2, H3, ..., Hn 代表建筑物的高度
题目分析
公式法
根据题目描述,我们可以得到一个关于机器人能量值的公式。设机器人跳到第k个建筑时的能量值为Ek,则:
Ek+1={Ek−(Hk+1−Ek),Hk+1>EkEk+(Ek−Hk+1),Hk+1≤Ek即:
Ek+1=2Ek−Hk+1并且:
Ek=2Ek−1−Hk根据这个递推公式,我们可以得到En与E0以及Hn之间的关系:
En=2En−1−Hn=2×(2En−2−Hn−1)−Hn=……=2nE0−n∑i=12n−iHi题目要求对于 ∀n,En≥0,则:
对于∀n,E0≥n∑i=1Hi2i所以符合题意的最小E0=⌈ ∑ni=1Hi2i ⌉
逆推
想象一下,机器人从第n个建筑往前跳,则有En=2En−1−Hn,即机器人在后一个建筑时的能量,加上建筑的高度,等于2倍的在前一个建筑时的能量,这样就可以依次获取到在前一个建筑的能量。
现在要求跳到第n个建筑的时候能量不小于0,则最小为0,那么设En=0,则En−1=⌈Hn2⌉,En−2=⌈Hn−1 + En−12⌉……E0=⌈H1 + E12⌉。
模拟过程
还可以直接模拟跳跃过程,搜索最小的E0。搜索过程可以使用二分查找。
初始的能量只要超过全部建筑高度之和sum,则必定可以跳到最后一个建筑。则可以在 [1, sum] 使用二分查找。
也可以从1开始,跳跃失败则指数增加,直到跳跃成功,然后在失败的最大值和成功值之间二分查找。例如开始E0=1,失败则设置E0=2、E0=4、E0=8,假设E0=8成功,则在 [4,8]之间二分查找。
代码实现
python实现
公式法
n = int(input())
hight = [int(i) for i in input().split()]
E = 0
for i,v in enumerate(hight):
E+=(v/2**(i+1))
import math
print(math.ceil(E))
逆推
n = int(input())
hight = [int(i) for i in input().split()]
hight.reverse()
import math
E = 0
for v in hight:
E= math.ceil((E+v)/2)
print(math.ceil(E))