【數組】B066_NK_機器人跳躍問題(二分 / 遞推)

一、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>hiE > h_i,跳上柱子 ii 機器人獲得 EhiE - h_i 能量
    • 如果 E<hiE < h_i,跳上柱子 ii 機器人失去 EhiE - h_i 能量
    • 總結 E=E(hiE)=2×EhiE = E - (h_i - E) = 2 × E - h_i
  • 由題意得,某個區間 [l,r][l, r] 一定存在一個值 e 可以讓機器人安全跳到終點,且這個值 e 越大越保險,基於這點,我們可以用二分來枚舉這個區間 [l,r][l, r]
  • 怎麼確定 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();
    }
}

複雜度分析

  • 時間複雜度:O(logmax)O(log max)
  • 空間複雜度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章