乘坐出租车在两个城市之间旅行
Posted
技术标签:
【中文标题】乘坐出租车在两个城市之间旅行【英文标题】:Travelling between two cities with cabs starting between 【发布时间】:2013-12-13 23:00:18 【问题描述】:您想使用某个数字从相距 m 英里的城镇 A 到 B 的士。在城镇之间(或其中一个城镇)的某个地方有一辆出租车 基地(每辆出租车从基地开始它的旅程)。每个驾驶室都有燃料 几英里的旅行(没有一辆出租车必须返回基地)。 确定您从 A 到 B 的旅行是否可行。
输入:
整数 m,d,n (1
输出:
一个整数:您必须使用的最少出租车数量 从 A 到 B 或 0(如果不可能)。
我试着用我最先想到的东西来解决它,(毫不奇怪)这不是一个好主意。也就是说,我所做的是:
sort(ALL(cabs));
reverse(ALL(cabs));
for(int i = 0; i < n; ++i)
toPosition = position <= d ? d-position : position - d;
if(cabs[0] <= toPosition) printf("0"); return 0;
position += (cabs[0]-toPosition);
cabs.erase(cabs.begin());
++solution;
if(position >= m) printf("%lld", solution); return 0;
现在,toPosition
是从基地到我们所在的当前position
的距离。然后,我们从基地乘坐油箱最满的驾驶室(如果没有这样的油箱可以让我们更接近)到B镇,没有解决办法)。我们相应地更改我们的position
(到给定出租车的最大容量),移除出租车,直到我们到达 B 镇。
我现在知道解决方案是错误的。我什至发现了一些失败的测试。但是,我不太明白为什么会这样。所以以测试为例
14 4 2
10 8
它输出 0 而它应该输出 2。我知道这是因为它想去 10->8 而这里正确的顺序是 8 -> 10。现在问题出在哪里:
为什么顺序在这个问题中很重要?如果无论如何我们都必须覆盖从 A 到 B 的所有距离,并且直到我们进入或到达基地位置之后,我们必须用每辆出租车回溯,为什么不使用能够最快完成回溯任务的那些呢?
【问题讨论】:
闻起来像家庭作业。您应该在标签中指定语言 闻起来像是在各种编程竞赛中训练过去的问题。我没有指定语言,因为它几乎不与 C++ 相关,而且我发布的代码是如此不言自明,以至于我认为没有必要。如果你们中的更多人认为我应该添加 C++ 标签,为什么不,我会这样做。 我想你会得到更多的关注。许多人订阅了 c++ 标签,因此如果他们选择接收更新,他们会收到有关此问题的通知。 【参考方案1】:假设您有 3 辆出租车,其中只有 1 辆有足够的燃料到达 A,它可以让您距离基地 1 英里;一个有足够的燃料让你从基地到B;最后一个有足够的燃料进行 2 英里的旅行。显然,您必须使用“最小”的驾驶室其次;如果您使用另一个,您将只是害羞B,一辆无法到达您的出租车,更不用说完成工作了。
所以,是的,顺序很重要。
【讨论】:
【参考方案2】: d:到驾驶室底座的距离 m:A到B的距离 int[] cabMilliage:每辆出租车可以行驶的里程我想出了一种可以使用的优化策略: 开始构建你的路径“向后”,从最后一辆出租车到第一辆。 要覆盖从驾驶室基地到B的距离,您将只使用一辆驾驶室,没有办法使用超过一辆,所以从选择这辆开始。 distBaseToB = m - d; 选择最小 cabMilliage[i] >= distBaseToB
计算这辆出租车接你的地点 pickUpPoint[0] = d - (cabMilliage[i] - distBaseToB)/2 现在,继续循环,选择可以在路径中更早接您并将您带到 pickUpPoint[0] 的最小 cabMilliage[] 直到你到达 A(或者因为没有足够的油,所以可以在路上接你的出租车用完了。)
【讨论】:
我相当肯定您的解决方案不会像我的那样有效,因为它基于相同的前提 - 尽可能使用当前可用的最满油箱的驾驶室或者没有答案。我和 Scott Hunter 提供的反例显然拒绝了这种态度。 啊,明白了! - 我们需要一些回溯:蛮力解决方案是一个函数,它在每次调用中选择一个 cab 并使用每个剩余的 cab 递归调用自身,直到它到达 B。恐怕这是 O(n!),它没有给出最少的出租车数量,但它回答了是否可以到达 B 的问题。以上是关于乘坐出租车在两个城市之间旅行的主要内容,如果未能解决你的问题,请参考以下文章