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)表示

  • F=当他没有回来收集剩余的谷物时 最后一次访问
  • G(x)%C-F=上次访问中的剩余谷物,然后消耗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);
    }