P4009 汽车加油行驶问题 - 分层图最短路
文章作者:gyro永不抽风
发布时间:2020年09月18日 - 22:09
最后更新:2020年09月19日 - 19:09
许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 转载请保留原文链接及作者!
题目
题目描述
给定一个 的方形网格,设其左上角为起点◎,坐标, 轴向右为正, 轴向下为正,每个方格边长为 ,如图所示。
一辆汽车从起点◎出发驶向右下角终点▲,其坐标为 。
在若干个网格交叉点处,设置了油库,可供汽车在行驶途中加油。汽车在行驶过程中应遵守如下规则:
-
汽车只能沿网格边行驶,装满油后能行驶 条网格边。出发时汽车已装满油,在起点与终点处不设油库。
-
汽车经过一条网格边时,若其 坐标或 坐标减小,则应付费用 ,否则免付费用。
-
汽车在行驶过程中遇油库则应加满油并付加油费用 。
-
在需要时可在网格点处增设油库,并付增设油库费用 (不含加油费用 )。
-
均为正整数, 且满足约束: 。
设计一个算法,求出汽车从起点出发到达终点所付的最小费用。
输入格式
文件的第一行是 的值。
第二行起是一个 的 方阵,每行 个值,至 行结束。
方阵的第 行第 列处的值为 表示在网格交叉点 处设置了一个油库,为 时表示未设油库。各行相邻两个数以空格分隔。
输出格式
程序运行结束时,输出最小费用。
输入输出样例
9 3 2 3 6 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 1 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0
12
说明/提示
题解
这道题一开始分层图的建立着实没有想出来,甚至看了题解都没想出来(我,菜)。所以特此记录。其实是这样的,因为一辆车总共只有$k$格油,所以我们可以建立$k + 1$层图,第$i$层图代表已经用掉了多少油。
接下来,我们考虑这个图如何构建:
- 我们用三元组$(i, j, l)$来表示点,意为:第$l$层中的$(i, j)$
- 因为题目中说不消耗钱的话只能向右或者向下,所以:
$$(i, j, l) \rightarrow (i, j + 1, l + 1), w = 0 $$
$$(i, j, l) \rightarrow (i + 1, j + 1, l), w = 0 $$
- 因为题目中说向左或者向上要花钱,所以:
$$(i, j, l) \rightarrow (i - 1, j, l + 1), w = b $$
$$(i, j, l) \rightarrow (i, j - 1, l + 1), w = b $$
- 在加油站的时候,情况和上面的就不太一样了,加油站的点应该都要指向该点的第$0$层(因为油必须加满),而且费用为$A$:
$$(i, j, l) \rightarrow (i, j, 0), w = A $$
- 还有就是不在加油站时可以随意添加油站,就是要花钱罢了:
$$(i, j, l) \rightarrow (i, j, 0), w = A + C $$
在图建立完之后,我们就可以发现:求最小费用其实就是求最短路,然后最后无论剩多少油都是可能的,所以我们要把$(n, n, l)$都遍历一下取一个最小。
还有一点:要注意不要数组越界,这就是为什么代码里有好多if
代码
1 |
|