【算法實驗四】--【動態規劃】--旅遊預算

1149.旅遊預算

時限:1000ms 內存限制:10000K  總時限:3000ms

描述

一個旅行社需要估算乘汽車從某城市到另一城市的最小費用,沿路有若干加油站,每個加油站收費不一定相同。旅遊預算有如下規則: 若油箱的油過半,不停車加油,除非油箱中的油不可支持到下一站;每次加油時都加滿;在一個加油站加油時,司機要花費2元買東西喫;司機不必爲其他意外情況而準備額外的油;汽車開出時在起點加滿油箱;計算精確到分(1元=100分)。編寫程序估計實際行駛在某路線所需的最小費用。

 

輸入

第一行爲起點到終點的距離(實數) 第二行爲三個實數,後跟一個整數,每兩個數據間用一個空格隔開。其中第一個數爲汽車油箱的容量(升),第二個數是每升汽油行駛的公里數,第三個數是在起點加滿油箱的費用(精確到分),第四個數是加油站的數量。(〈=50)。接下去的每行包括兩個實數,每個數據之間用一個空格分隔,其中第一個數是該加油站離起點的距離,第二個數是該加油站每升汽油的價格(元/升)。加油站按它們與起點的距離升序排列。所有的輸入都有一定有解。

 

輸出

共兩行,每行都有換行 第一行爲一個實數和一個整數,實數爲旅行的最小費用,以元爲單位,精確到分,整數表示途中加油的站的N。第二行是N個整數,表示N個加油的站的編號,按升序排列。數據間用一個空格分隔,最後一個數據後也輸出空格,此外沒有多餘的空格。

 

輸入樣例

516.3

15.7 22.1 20.87 3

125.4 1.259

297.9 1.129

345.2 0.999

 

輸出樣例

38.09 1

2

解析:額,我剛看到這道題,好像不是很會做,讓我解析一下。每當走到一個站,檢查一下油箱裏的油,若超過一半且能堅持到下一站,按題意就堅決不能加油,若到不了則肯定要加油。若少於一半,且到不了下一站,肯定要加油,若少於一半但能到達下一站,就需要斟酌一下了,可以選擇加滿或者不加,加滿是因爲若這裏的油價便宜就加滿,不加滿是因爲這裏的油價貴。

對於實現,dp函數裏面傳進去一個參數 i ,返回值應是 i 到終點站的最小花費(所以問題的答案就是dp(0))。對於當前的 i ,此時需要檢查它是否能到達下一站,注意此時必定是滿油狀態。那麼遍歷i 後邊到終點站的每一個站,看能否到達其中的一些站。此時可能會發生的情況有如下幾種:情況一直接能到達終點站,那麼直接退出,返回0就可以;情況二看是否已經遍歷過此站,如果有那麼肯定已經記錄了此站到終點站的最小花費(因爲dp函數就是得到第 i 個站到終點站的最下花費,所以肯定會有備忘錄來記錄;情況三就需要進入for函數,遍歷後邊的每一個 j 站,若能到達j 站且油箱還剩一半的油,此時按規定不能加油,所以不加油直接跳到下一個站即j+1檢查,若當前的j站就是終點站則不需要加油,花費記爲0即可,若不是這兩種,就要加油,然後把費用記錄下來,即更新當前i到終點站的費用等與剛剛加油的費用(也就是i到j的費用)加上j到終點站的費用,同時記錄下來加油的站點j。

此時有個問題可能大家會注意到,如果我當前油量不足一半但是我可以到達下一站,那麼我可以選擇加油或者不加油,然後比較這兩者的代價誰更小才記錄啊。這個是正確的,這個解法也恰恰就遵循了這個,因爲在遍歷i後邊的每個站點j時,我都是在當前的j站點加了油,這就是第一種加油的情況,然後我把這種方法的代價給更新到備忘錄裏邊了,但是此時還是在for循環裏邊,循環到下一個j時,此時我是在上一個站點不加油的方法,此時我又得出了新的不加油方法的代價,此時與備忘錄進行代價小的比較,將代價小的寫入。

此時的dp代碼大概如下:

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章