LeetCode刷题:871. Minimum Number of Refueling Stops

LeetCode刷题:871. Minimum Number of Refueling Stops

原题链接:https://leetcode.com/problems/minimum-number-of-refueling-stops/

A car travels from a starting position to a destination which is target miles east of the starting position.

Along the way, there are gas stations.  Each station[i] represents a gas station that is station[i][0] miles east of the starting position, and has station[i][1] liters of gas.

The car starts with an infinite tank of gas, which initially has startFuel liters of fuel in it.  It uses 1 liter of gas per 1 mile that it drives.

When the car reaches a gas station, it may stop and refuel, transferring all the gas from the station into the car.

What is the least number of refueling stops the car must make in order to reach its destination?  If it cannot reach the destination, return -1.

Note that if the car reaches a gas station with 0 fuel left, the car can still refuel there.  If the car reaches the destination with 0 fuel left, it is still considered to have arrived.

 

Example 1:

Input: target = 1, startFuel = 1, stations = []
Output: 0
Explanation: We can reach the target without refueling.
Example 2:

Input: target = 100, startFuel = 1, stations = [[10,100]]
Output: -1
Explanation: We can't reach the target (or even the first gas station).
Example 3:

Input: target = 100, startFuel = 10, stations = [[10,60],[20,30],[30,30],[60,40]]
Output: 2
Explanation: 
We start with 10 liters of fuel.
We drive to position 10, expending 10 liters of fuel.  We refuel from 0 liters to 60 liters of gas.
Then, we drive from position 10 to position 60 (expending 50 liters of fuel),
and refuel from 10 liters to 50 liters of gas.  We then drive to and reach the target.
We made 2 refueling stops along the way, so we return 2.
 

Note:

1 <= target, startFuel, stations[i][1] <= 10^9
0 <= stations.length <= 500
0 < stations[0][0] < stations[1][0] < ... < stations[stations.length-1][0] < target

汽车从起点出发驶向目的地,该目的地位于出发位置东面 target 英里处。

沿途有加油站,每个 station[i] 代表一个加油站,它位于出发位置东面 station[i][0] 英里处,并且有 station[i][1] 升汽油。

假设汽车油箱的容量是无限的,其中最初有 startFuel 升燃料。它每行驶 1 英里就会用掉 1 升汽油。

当汽车到达加油站时,它可能停下来加油,将所有汽油从加油站转移到汽车中。

为了到达目的地,汽车所必要的最低加油次数是多少?如果无法到达目的地,则返回 -1 。

注意:如果汽车到达加油站时剩余燃料为 0,它仍然可以在那里加油。如果汽车到达目的地时剩余燃料为 0,仍然认为它已经到达目的地。

 

示例 1:

输入:target = 1, startFuel = 1, stations = []
输出:0
解释:我们可以在不加油的情况下到达目的地。
示例 2:

输入:target = 100, startFuel = 1, stations = [[10,100]]
输出:-1
解释:我们无法抵达目的地,甚至无法到达第一个加油站。
示例 3:

输入:target = 100, startFuel = 10, stations = [[10,60],[20,30],[30,30],[60,40]]
输出:2
解释:
我们出发时有 10 升燃料。
我们开车来到距起点 10 英里处的加油站,消耗 10 升燃料。将汽油从 0 升加到 60 升。
然后,我们从 10 英里处的加油站开到 60 英里处的加油站(消耗 50 升燃料),
并将汽油从 10 升加到 50 升。然后我们开车抵达目的地。
我们沿途在1两个加油站停靠,所以返回 2 。


算法设计

package com.bean.algorithm.basic;

public class LeetCode871 {
	
	/*
	 * 动态规划算法
	 * dp[i][j]代表在station[i]剩余汽油量为j
	 * 我们把起点0作为第一个加油站 
	 * 这时,dp[0][0]=startFuel
	 * 初始化 dp[i][j]=-1, 表示我们使用j油量时不能达到station[i].
	 * 状态方程为
	 * remain=dp[i][j]+station[i][0]-station[i+1][0]
	 * 如果 remain>0, 有两种情况:
	 * 无燃油时, dp[i+1][j]=max(dp[i+1][j], remain)
	 * 有燃油时, dp[i+1][j+1]=max(dp[i+1][j+1], remain+station[i+1][1])
	 * 针对每一对(i,j),检查条件 dp[i][j]+station[i][0]>=target, 
	 * 然后返回满足条件的最小的j值.
	 * 
	 * */

	public int minRefuelStops(int target, int startFuel, int[][] stations) {
        int ret = 10000;
        int N = stations.length;

        int dp[][] = new int[N + 1][N + 1];
        for (int i = 0; i < N + 1; i++) {
            for (int j = 0; j < N + 1; j++) {
                dp[i][j] = -1;
            }
        }
        //初始设定从0号开始,油量为0。
        dp[0][0] = startFuel;

        for (int i = 0; i < N + 1; i++) {
            for (int j = 0; j < N + 1; j++) {
                if (dp[i][j] + (i >= 1 ? stations[i - 1][0] : 0) - target >= 0) {
                    ret = Math.min(ret, j);
                }
                if (i < N) {
                    int remain = dp[i][j] + (i >= 1 ? stations[i - 1][0] : 0) - stations[i][0];
                    if (remain >= 0) {
                        dp[i + 1][j] = Math.max(dp[i + 1][j], remain);
                        dp[i + 1][j + 1] = Math.max(dp[i + 1][j + 1], remain + stations[i][1]);
                    }
                }
            }
        }

        return ret >= 10000 ? -1 : ret;
    }
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		/*
		 * Input: target = 100, startFuel = 10, stations = [[10,60],[20,30],[30,30],[60,40]]
		 * Output: 2
		 * We start with 10 liters of fuel.
		 * We drive to position 10, expending 10 liters of fuel.  
		 * We refuel from 0 liters to 60 liters of gas.
		 * Then, we drive from position 10 to position 60 (expending 50 liters of fuel),
		 * and refuel from 10 liters to 50 liters of gas.  We then drive to and reach the target.
		 * We made 2 refueling stops along the way, so we return 2.
		 * */
		
		int target = 100;
		int startFuel = 10;
		int[][] stations =new int[][] {
			{10,60},{20,30},{30,30},{60,40}
		};
		
		LeetCode871 leetcode871=new LeetCode871();
		int result = leetcode871.minRefuelStops(target, startFuel, stations);
		
		System.out.println("result = "+result);
		
		}
	}


程序运行结果:

result = 2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值