[LeetCode] 871. Minimum Number of Refueling Stops
題:https://leetcode.com/problems/minimum-number-of-refueling-stops/
題目大意
起點有油 startFuel 的車,想行駛到 終點 target位置。途中有多個加油站 station 可以加油,其中station[0] 表示與起點的距離,station[1]表示可以加的油,且 車在行駛過程中必須保持 油 >=0 。
求車能到達target的最少加油數,若不能達到 返回 -1。
思路
整個行駛過程十分像 0 -1 背包選擇問題,對于每個加油站選擇是否加油。
狀態:
dp[i][j] : 經過 i 個加油站,加了 j 次油后,車能行駛的最遠距離。
初始化狀態:
dp[i][0] = startFuel ,若全程 未加油,那么車能行駛的里程便是 最初油startFuel 的 距離。
狀態轉移:
dp[i][j] = max(dp[i-][j], dp[i-1][j-1] + stations[i-1][1] if dp[i-1][j-1] >= stations[i-1][0] else 0)
這里的意思是:若在 i 加油站不加油,那么 dp[i][j] = dp[i-][j],若選擇加油 且 dp[i-1][j-1] >= stations[i-1][0] ,那么 dp[i][j] = max(dp[i-][j], dp[i-1][j-1] + stations[i-1][1] if dp[i-1][j-1] )
最后我們只用看 dp[stations.length][j]>= target 中的 最小 j 。
class Solution {public int minRefuelStops(int target, int startFuel, int[][] stations) {int N = stations.length;int[][] dp = new int[N+1][N+1];for(int i =0 ;i <= N ;i++)dp[i][0] = startFuel;for(int i = 1 ; i <= N ;i++)for(int j = 1 ; j <=N; j++){dp[i][j] = dp[i-1][j];if(dp[i-1][j-1] >= stations[i-1][0])dp[i][j] = Math.max(dp[i][j],dp[i-1][j-1] + stations[i-1][1]);} for(int j = 0 ; j <= N ;j++)if(dp[N][j] >= target)return j;return -1;} }0-1 背包 的典型壓縮
class Solution {public int minRefuelStops(int target, int startFuel, int[][] stations) {PriorityQueue<Integer> pq = new PriorityQueue(new Comparator<Integer>(){public int compare(Integer o1,Integer o2){return o2 - o1;}});int dis = startFuel;int cnt = 0;int index = 0;while(true){if(dis >= target)return cnt;while(index < stations.length && stations[index][0] <= dis){pq.add(stations[index++][1]);}if(pq.isEmpty())break;dis += pq.peek();pq.poll();cnt++;}return -1;} }方法二 貪心
車行駛,若車到達target,那么返回當前的加油次數。
若沒有 用 大頂堆 記錄 在油耗盡時 經過的 加油站,并將該加油站的加油數加入大頂堆中。
取 最大的 加油量 作為 車 能 增加的里程數數,繼續上部操作。
當 大頂堆為空時,返回 -1
這里是用的貪心,不斷去 反悔,假設 我們 取了 經過的 最好的加油站。
總結
以上是生活随笔為你收集整理的[LeetCode] 871. Minimum Number of Refueling Stops的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 预处理器less
- 下一篇: Windows下Tomcat安装