1. 程式人生 > >守望者的逃離

守望者的逃離

實現 之間 遇難 包括 狀態 所有 strong 方法 任務

題目描述

惡魔獵手尤迪安野心勃勃,他背著了暗夜精靈,率領深藏在海底的娜迦族企圖叛變。守望者在與尤迪安的交鋒中遭遇了圍殺,被困在一個荒蕪的大島上。為了殺死守望者,尤迪安開始對這個荒島施咒,這座島很快就會沈下去。到那時,島上的所有人都會遇難。守望者的跑步速度為17m/s,以這樣的速度是無法逃離荒島的。慶幸的是守望者擁有閃爍法術,可在1s內移動60m,不過每次使用閃爍法術都會消耗魔法值10點。守望者的魔法值恢復的速度為4點/s,只有處在原地休息狀態時才能恢復。 現在已知守望者的魔法初值m,他所在的初始位置與島的出口之間的距離s,島沈沒的時間t。你的任務是寫一個程序幫助守望者計算如何在最短的時間內逃離荒島,若不能逃出,則輸出守望者在剩下的時間內能走的最遠距離。註意:守望者跑步、閃爍或休息活動均以秒為單位,且每次活動的持續時間為整數秒。距離的單位為米。

輸入

輸入只有一行,包括三個非負的整數m,s,t。

輸出

輸出有二行。第一行只有一個字符串“Yes”或“No”數,表示守望者能否逃離荒島。第二行只有一個整數,表示逃離荒島的最短時間或能走的最遠距離。

還記得16年做的時候是抄書上的標程的。現在回頭去看看這題,這方法好妙啊。

先講標程——

首先我們可以知道當魔法充足的時候,用魔法是比跑步更優的。於是開始初始化。

第一遍 i = 1..t 是假設守望者只有使用/恢復魔法兩種操作。得到初始 f 數組。

第二遍 i = 1..t 是假設守望者每一秒都跑步,再取max(f[i], f[i-1]+17) 

  這個max操作的正確性怎麽確定呢?

  我們已經知道跑步的時間有可能用來恢復魔法更優

  在第一遍的操作裏,已經確定了每一次最快速使用魔法的方式;第二遍操作時,如果將跑步時間用來恢復魔法能夠更優,那麽當 i 枚舉到一個值時,不難發現f[i] > f[i-1] + 17,所以第二遍中這一部分的操作對最終結果並沒有影響。

由此觀之,最終 f 數組表示的是每一秒守望者最多能到達的路程,而不是整條路線最優解的過程,因此解決了第二問。

DFS思路——

因為守望者還有一個魔法值m,所以最優性剪枝時比較麻煩:並不能確保之前的一種當前狀態較優的方法會最終會被保留,因為還可以用魔法呢。

所以還要保存一個mi數組記錄,而且在確定最終解時實現比較麻煩。

守望者的逃離