你想要从A镇到B镇,使用一些号码,相隔数英里 出租车。在城镇之间(或其中一个城镇)的某个地方有一辆出租车 基地(每个出租车从基地开始行程)。每辆出租车都有燃料 几英里的旅行(没有一个出租车必须返回基地)。 确定您是否可以从A到B旅行。
INPUT:
整数m,d,n(1 <= d <= m <= 10 ^ 8,1 <= n <= 500,000)意思是(在 订购):从A到B的距离,从A到驾驶室底座的距离,数量 驾驶室。在那之后,n个整数意味着第i个驾驶室为x_i-th提供燃料 几英里的旅行。
输出:
一个整数:您必须使用的最少数量的出租车 如果不可能,从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 - &gt; 10.现在问题就出现了:
为什么订单在这个问题上很重要?如果我们必须覆盖从A到B的所有距离,直到我们在基地位置之内或之后,我们必须使用每个驾驶室回溯,为什么不使用那些最快进行回溯任务的那些?
答案 0 :(得分:0)
想象一下,你有3个出租车,其中只有1个有足够的燃料可以到达A,它可以让你距离基地1英里;一个人有足够的燃料让你从基地到B;最后一次有足够的燃料进行2英里的旅行。显然,你必须使用“最小”的驾驶室;如果你使用了另一个,那么你只是羞于B,驾驶室无法联系到你,更不用说完成工作了。
所以,是的,订单确实很重要。
答案 1 :(得分:0)
我想出了一个可以使用的优化策略: 开始构建你的路径'向后',从最后一个驾驶室到第一个驾驶室。 要覆盖从驾驶室底座到B的距离,您将只使用一个驾驶室,无法使用多个驾驶室,因此请从选择此驾驶室开始。 distBaseToB = m - d; 选择最小cabMilliage [i]&gt; = distBaseToB
计算出驾驶室接你的地方 pickUpPoint [0] = d - (cabMilliage [i] - distBaseToB)/ 2 现在,继续循环,选择最小的cabMilliage [],它可以在路径中提前接你并带你到pickUpPoint [0] 直到你到达A(或者因为他们没有足够的汽油而用完可以在路上接你的出租车。)