# 问题描述
油价飞升的今天,我们尽量减少花费。我们出门旅游,有时候租车去旅游也是一种不错的方式。这次我们这次旅游是从「青海湖」到「景点 X」,景点 X 可以是「敦煌」、「月牙泉」等,线路的路径是唯一的,假设我们每走 1 km 消耗 1 L 的油,车油箱容量 400L。比如:如果「景点 X」是敦煌,我们在青海湖租车前油箱是 200L 的,在「景点 X」(敦煌)还车的时候也是 200L 的,路上有很多加油站,加油站在青海湖和「景点 X」的连线上。
## 输入格式
第 1 行表示「青海湖」到「景点 X」的距离,距离最远不超过 10000 km。
第 2 行表示接下来 N 行表示 N 个加油站(N 为正整数)。
接下来 N(1 <= N <= 100)行表示,每一个加油站情况。每一个加油站包括距离「景点 X」的距离 a km(0 <= a <= 10000),以及每升汽油的价格 b 元(0 <= b <= 2000),a 和 b 均为正整数。
## 输出格式
如果不能到达目的地「景点 X」,输出 Impossible。
如果能到达目的地「景点 X」,输出最小花费多少元。
**输入样例**:
500
4
100 1
200 30
400 40
300 20
**输出样例**:
4300
def solution(distance, n, gas_stations):
# Please write your code here
#线性动态规划
#n的值在下面的代码中可以发生改变,代表有效的加油站数量
#将终点距离加到加油站列表中,方便后续处理(相当于把终点当成最后一个加油站了)
gas_stations.append((distance,0))
#按照距离加油站的距离长短排序
gas_stations.sort(key=lambda x:x[0])
#距离数组,表示每个加油站和前一个加油站的距离
dis=[0]*(n+1)
dis[0]=gas_stations[0][0]
for i in range(1,n+1):
dis[i]=gas_stations[i][0]-gas_stations[i-1][0]
#dp[i][j]表示到达第i个加油站油量剩余j时的最小花费
dp=[[float('inf')]*410 for _ in range(110)]
#起点设置为0
dp[0][200]=0
#动态规划过程
for i in range(1,n+1):
#意味着找到最后一个有效的加油站
if gas_stations[i-1][0]==distance:
n=i-1
break
#j表示到达第 i 个加油站时油量剩余为 j 的情况,k表示到达第 i - 1 个加油站时油量剩余为 k 的情况
for j in range(401):
for k in range(401):
#如果从当前加油站的前一个加油站出发,到达当前加油站时油量足够,并且当前加油站有油价信息
if j+dis[i-1]-k>=0 and len(gas_stations[i-1])>1:
#更新dp[i][j]为到达当前加油站剩余j的最小花费
cost = (j + dis[i - 1] - k) * gas_stations[i - 1][1]
dp[i][j]=min(dp[i][j],dp[i-1][k]+cost)
if n<1 or 200+dis[n-1]<0 or dp[n][200+dis[n-1]]==float('inf'):
return "Impossible"
return dp[n][200+dis[n-1]]
if __name__ == "__main__":
# You can add more test cases here
gas_stations1 = [(100, 1), (200, 30), (400, 40), (300, 20)]
gas_stations2 = [(100, 999), (150, 888), (200, 777), (300, 999), (400, 1009), (450, 1019), (500, 1399)]
gas_stations3 = [(101,), (100, 100), (102, 1)]
gas_stations4 = [(34, 1), (105, 9), (9, 10), (134, 66), (215, 90), (999, 1999), (49, 0), (10, 1999), (200, 2), (300, 500), (12, 34), (1, 23), (46, 20), (80, 12), (1, 1999), (90, 33), (101, 23), (34, 88), (103, 0), (1, 1)]
print(solution(500, 4, gas_stations1) == 4300)
print(solution(500, 7, gas_stations2) == 410700)
print(solution(500, 3, gas_stations3) == "Impossible")
print(solution(100, 20, gas_stations4) == 0)
print(solution(100, 0, []) == "Impossible")