出处: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; }
输出结果: