一、Problem
机器人正在玩一个古老的基于DOS的游戏。游戏中有N+1座建筑——从0到N编号,从左到右排列。
编号为0的建筑高度为0个单位,编号为 i 的建筑高度为H(i)个单位。起初,机器人在编号为0的建筑处。每一步,它跳到下一个(右边)建筑。
假设机器人在第k个建筑,且它现在的能量值是E,下一步它将跳到第k+1个建筑。
如果H(k+1)>E,那么机器人就失去H(k+1)-E的能量值,否则它将得到E-H(k+1)的能量值。
游戏目标是到达第N个建筑,在这个过程中能量值不能为负数个单位。现在的问题是机器人至少以多少能量值开始游戏,才可以保证成功完成游戏?
输入格式
第一行输入整数N。
第二行是N个空格分隔的整数,H(1),H(2),…,H(N)代表建筑物的高度。
输出格式
输出一个整数,表示所需的最少单位的初始能量值上取整后的结果。
数据范围
1≤N,H(i)≤105,
输入样例1:
5
3 4 3 2 4
输出样例1:
4
二、Solution
方法一:二分
- 规则:
- 如果 ,跳上柱子 机器人获得 能量
- 如果 ,跳上柱子 机器人失去 能量
- 总结
- 由题意得,某个区间 一定存在一个值 e 可以让机器人安全跳到终点,且这个值 e 越大越保险,基于这点,我们可以用二分来枚举这个区间
- 怎么确定 r 呢?看数据范围…
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
static class Solution {
int n, max = (int) 1e5 + 5, h[];
boolean check(int e) {
for (int i = 0; i < n; i++) {
e = 2 * e - h[i];
if (e >= max) return true;
if (e < 0) return false;
}
return true;
}
void init() {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
n = sc.nextInt();
h = new int[n];
for (int i = 0; i < n; i++) h[i] = sc.nextInt();
int l = 0, r = 100000;
while (l < r) {
int mid = l + r >>> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
System.out.println(r);
}
}
public static void main(String[] args) throws IOException {
Solution s = new Solution();
s.init();
}
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,