一、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();
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,