商人胡萝卜问题

出处:http://blog.csdn.net/utimes/article/details/8454801

问题:

一个商人骑一头驴要穿越1000公里长的沙漠,去卖3000根胡萝卜。 已知驴一次性可驮1000根胡萝卜,但每走1公里又要吃掉1根胡萝卜。 问:商人最多可卖出多少胡萝卜?

分析:

要使到达终点的萝卜最多,就不能浪费,要么到达了终点,要么被吃在了路上。 所以要把3000个萝卜整体的前移,一次只可以带1000个萝卜,所以3000个要都前移需要出去回来、出去回来、再出去。  同样的路要走5次。走到哪个点呢? 200公里处! 为什么? 注意了,200公里来回5次的话刚好可以剩下2000个胡萝卜!  而2000个萝卜要整体前移,需要的不是走5次,而是3次! 所以如果走的超过200公里,则超过的部分相对就多吃了萝卜。 再把2000个萝卜朝前移动,需要走三次,走到哪里呢? 再往前走333公里吧,也就是533公里处。 为什么呢? 同上面的道理,因为走三趟333公里后,剩下的刚好是1001个萝卜!是最接近1000且大于1000的数字。如果走多了,则剩下的 萝卜会少于1000,这多走的部分相对我们这里的方案会多吃萝卜滴。 好了,到533公里处了,现在有1001个萝卜,扔1个吧, 是有点可惜,可你有什么办法,或者你也可以把它吃了。然后带上剩下的1000个萝卜,朝终点冲吧。后面还有467公里。到达终点时,所剩下的就是533个萝卜。最终剩下的萝卜数 = 花费2000个萝卜所能前进的公里数

这2000个萝卜的价值不只是让你前进了一段距离,而且会使你在走花费完它们后手头还有1000个萝卜! 如何能让2000个萝卜的价值最大,也就是在手头有1000个萝卜时前进的最远呢 ? 嘿嘿,上面的方案!

答案:

带1000到200公里处,返回。如此往复,需要走五次,吃1000胡萝卜。可将2000胡萝卜带到200公里处。  重复以上过程,把萝卜带到533公里处。需要走三次,走到后余下1001个胡萝卜。   扔掉一个。带上剩下的1000个。冲到终点。余下533个胡萝卜。 533即为最终答案。 做到这里不难。难的是怎么证明这个533 就是最优解!

代码:

//胡萝卜问题  
  
#include <iostream>    
#include <math.h>   
  
using namespace std;  
    
int main()    
{    
    int i = 0; //循环变量    
    int s = 1000; //总里程    
    int n = 3000; //总萝卜数    
    for(i = 0; i < s; i++)    
    {    
        //计算要分几次搬运,是下取整。    
        int x = (int)ceil((double)n/1000);    
        //如果回去搬萝卜的代价比搬过来的萝卜数量大,说明没价值,不要返回去搬,扔了。    
        if(n % 1000 != 0 && n % 1000 <= x)    
        {    
            x -= 1;    
        }    
        //如果要回去多次搬运,则往返路程要计算好。两次搬运要走三次路。    
        if(x == 2)    
        {    
            x += 1;    
        }    
        //如果要回去多次搬运,则往返路程要计算好。三次搬运要走五次路。一次搬运当然就一次路就OK了。    
        else if(x == 3)    
        {    
            x += 2;    
        }    
        //让驴吃掉的萝卜。    
        n -= x;    
    }    
    cout << "商人最多可卖出的胡萝卜数量为:" << n << endl;    
    
    return 0;    
}  

输出结果:

原文地址:https://www.cnblogs.com/smilehuanxiao/p/3418349.html