美文网首页
871. 最低加油次数

871. 最低加油次数

作者: 漫行者_ | 来源:发表于2021-11-26 22:47 被阅读0次

    871. 最低加油次数

    很好的题目,不管是动态规划还是最大堆。
    最大堆

    class Solution {
        public int minRefuelStops(int target, int startFuel, int[][] stations) {
           int sum = startFuel;
           Queue<Integer> maxHeap = new PriorityQueue<>((e1,e2)->{
               return e2-e1;
           });
           int n = stations.length;
           int res =0;
           for(int i=0; i<n; i++){
               while(sum < stations[i][0]) {
                   if(maxHeap.size() == 0) {
                       return -1;
                   }
                   sum += maxHeap.poll();
                   res++;
               }
                maxHeap.add(stations[i][1]);
           }
            while(sum < target) {
                if(maxHeap.size() == 0) {
                       return -1;
                }
                sum += maxHeap.poll();
                res++;
            }
            return res;
    
        }
    }
    

    动态规划

     int minRefuelStops(int target, int startFuel, vector<vector<int>>& stations) {
            if(startFuel>=target)
                return 0;
            int n=stations.size();
            //dp[i][j]为经过了i个加油站、加了j次油能跑的最远距离(当然0<=j<=i)
            //vector<vector<int>> dp(n+1,vector<int> (n+1,0));
            //用二维int dp数组会在提交时发现在一个测试案例中两根整型相加
            //超过了INT_MAX而溢出报错,故这里换用long
            //因不支持vector<vector<long>> dp(n+1,vector<int> (n+1,0)); 
            //故换用下面四行来实现
            long dp[n+1][n+1];  
            for(int i=0;i<n+1;++i)
                for(int j=0;j<n+1;++j)
                    dp[i][j]=0; //dp数组初始化
            
            //开成n+1的长度是因为把起点视为第0个加油站:起始状态处理
            for(int i=0;i<n+1;++i)
                dp[i][0]=startFuel; //甭管经过了几个站,一次油也不加那最多跑的就是startFuel的距离
            
            for(int i=1;i<n+1;++i)
            {
                for(int j=1;j<=i;++j)
                {
                    if(dp[i-1][j]>=stations[i-1][0])  //在第i站不加油
                        dp[i][j]=dp[i-1][j];
                    if(dp[i-1][j-1]>=stations[i-1][0]) //在第i站加油
                        dp[i][j]=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;
        }
    

    相关文章

      网友评论

          本文标题:871. 最低加油次数

          本文链接:https://www.haomeiwen.com/subject/pitfxrtx.html