Algorithm 算法-可运输的最大谷物数量
我在谷歌遇到一个面试问题,我无法解决: 在距离城镇Algorithm 算法-可运输的最大谷物数量,algorithm,Algorithm,我在谷歌遇到一个面试问题,我无法解决: 在距离城镇Dkm的绿洲上有一堆Nkg谷物。谷物需要用骆驼车运输,骆驼车的初始位置是绿洲。该车一次可运送Ckg谷物。骆驼在运输谷物时将谷物用作燃料。它消耗Fkg/km 编写一个函数,计算可运输到城镇的最大谷物量(Xkg) 我试着使用递归,但如果不把自己弄糊涂的话,我就不能走得更远 以下是我目前掌握的情况: number of transports = N / C fuel amount for distance D = D * F X = N - ((
D
km的绿洲上有一堆N
kg谷物。谷物需要用骆驼车运输,骆驼车的初始位置是绿洲。该车一次可运送C
kg谷物。骆驼在运输谷物时将谷物用作燃料。它消耗F
kg/km
编写一个函数,计算可运输到城镇的最大谷物量(X
kg)
我试着使用递归,但如果不把自己弄糊涂的话,我就不能走得更远 以下是我目前掌握的情况:
number of transports = N / C
fuel amount for distance D = D * F
X = N - ((number of transports) * 2 * (fuel amount for distance D))
作为一个想法,当绿洲中的谷物超过D*F时,骆驼将带着C千克或绿洲中剩下的多少来旅行。骆驼在那里的旅途中消耗了D*F千克的粮食,卸下了-2*D*F千克的粮食,如果剩下足够的粮食,就可以返回。这只是一个猜测。我不是绝对肯定 设G(x)表示从源输送到距离x的最大谷物量。 然后 现在,G(0)=N,我们需要用上面的公式求出G(D) 第二项max(F,G(x)%C-F)表示
我认为这个问题最好是迭代地向前解决。我要把决策点分出来。如果我写一个公式,我会用?:所有结果都以千克为单位
The first question is whether there is enough grain, and cart capacity, to
justify an initial trip from oasis to town. The camel would eat FD, so
if FD >= min(N,C) the answer is 0
If FD < min(N,C), the net amount transferred on the initial oasis to town
trip is min(N,C)-FD.
The camel is now in town, the remaining grain pile is N-min(N,C), and we
have to decide whether to send it back again. If C <= 2FD, no round trip
can be profitable.
Otherwise consider a round trip with at least C remaining at the oasis. That
gains net C-2FD (FD put in the cart in town to keep the camel fed getting
to the oasis, C-FD remaining in the cart when it gets back to town).
If N>C, we can do floor((N-C)/C) of those round trips, net gain
floor((N-C)/C)*(C-2FD).
After doing the initial run and any full cart round trips, the remaining
grain pile is N%C, the remainder on dividing N by C.
If N%C > 2FD it is worth doing a final trip to empty the grain pile, with
an additional net gain of N%C-2FD.
第一个问题是是否有足够的粮食和运输车容量
证明从绿洲到城镇的初次旅行是合理的。骆驼会吃FD,所以
如果FD>=min(N,C),则答案为0
如果FD2FD,则值得进行最后一次行程,以清空谷物堆,同时
额外净增益N%C-2FD。
假设N、D、C和F是输入,-
float computeMaxGrains(float N, float D, float C, float F)
{
//Case when the cart can carry all grains at once
if(N <= C)
{
float remainingGrains = N - D*F;
if(remainingGrains >= 0)
{
return remainingGrains;
}
else
{
//out of fuel
return 0;
}
}
// Grains consumed per Km = (Total Number of Trips) * F
// Total Number of Trips = 2*(N/C) + 1
float grainsConsumedPerKm = (float) (2*(Math.floor(N/C)) + 1);
// Remaining grains after Camels fuel = C*(N/C - 1)
float remainingGrains = (float) (C*(Math.floor(N/C)));
// Distance that the Camel is able to travel before the camel is
// 1 less round trip =
// (N - Remaining Grains) / grainsConsumedPerKm
// From equation N - (grainsConsumedPerKm * distanceTravelled) =
// Remaining Grains
float distanceTravelled = (N - remainingGrains) / grainsConsumedPerKm;
if(distanceTravelled >= D)
{
return N - (D * grainsConsumedPerKm);
}
//Use recursion for every 1 less round trip
return computeMaxGrains(remainingGrains, D-distanceTravelled, C, F);
}
float computeMaxGrains(浮点N、浮点D、浮点C、浮点F)
{
//当大车可以同时运送所有谷物时的情况
如果(N=0)
{
返回剩余谷物;
}
其他的
{
//燃料耗尽
返回0;
}
}
//每公里消耗的谷物=(总行程数)*F
//总行程数=2*(N/C)+1
浮球粒径ConsumedPerkm=(浮球)(2*(数学地板(N/C))+1);
//骆驼燃料后的剩余谷物=C*(N/C-1)
浮球剩余颗粒=(浮球)(C*(数学地板(N/C));
//骆驼在移动之前能够移动的距离
//1减去往返=
//(N-剩余晶粒)/晶粒度消耗Perkm
//根据方程N-(颗粒消耗的Perkm*行驶距离)=
//余粒
浮动距离旅行=(N-剩余颗粒)/颗粒消耗量/公里;
如果(行驶距离>=D)
{
返回N-(D*颗粒消耗量erkm);
}
//每少1次往返使用递归
返回计算最大粒径(剩余粒径,D-行驶距离,C,F);
}
提示:骆驼每次往返都会携带C
kg谷物。提示2:如果骆驼在目的地卸下所有的粮食,它会在回来的路上饿死。提示3:骆驼不需要返回绿洲。非常清楚的分析,但它有助于明确提到C-2FD可能为负值的可能性(即,从城镇到绿洲来回可能是净损失,即使第一次旅行是净收益)@j_random_hacker谢谢-我把那句话写在草稿里,不知怎的就把它删掉了。我编辑了我的答案,把它放回原处。谢谢帕特里夏的详细分析。太棒了。感谢takyon的精彩解释和递归在这里的帮助。我想你在计算grainsConsumedPerKm时错过了F的乘法?
float computeMaxGrains(float N, float D, float C, float F)
{
//Case when the cart can carry all grains at once
if(N <= C)
{
float remainingGrains = N - D*F;
if(remainingGrains >= 0)
{
return remainingGrains;
}
else
{
//out of fuel
return 0;
}
}
// Grains consumed per Km = (Total Number of Trips) * F
// Total Number of Trips = 2*(N/C) + 1
float grainsConsumedPerKm = (float) (2*(Math.floor(N/C)) + 1);
// Remaining grains after Camels fuel = C*(N/C - 1)
float remainingGrains = (float) (C*(Math.floor(N/C)));
// Distance that the Camel is able to travel before the camel is
// 1 less round trip =
// (N - Remaining Grains) / grainsConsumedPerKm
// From equation N - (grainsConsumedPerKm * distanceTravelled) =
// Remaining Grains
float distanceTravelled = (N - remainingGrains) / grainsConsumedPerKm;
if(distanceTravelled >= D)
{
return N - (D * grainsConsumedPerKm);
}
//Use recursion for every 1 less round trip
return computeMaxGrains(remainingGrains, D-distanceTravelled, C, F);
}