面试题:火车运煤问题

hondely 2011-09-29 05:26:22
你是山西的一个煤老板,你在矿区开采了有3000吨煤需要运送到市场上去卖,从你的矿区到市场有1000公里,你手里有一列烧煤的火车,这个火车最多只能装1000吨煤,且其能耗比较大——每一公里需要耗一吨煤。请问,作为一个懂编程的煤老板的你,你会怎么运送才能运最多的煤到集市?







...全文
5466 168 打赏 收藏 转发到动态 举报
写回复
用AI写文章
168 条回复
切换为时间正序
请发表友善的回复…
发表回复
森之树 2012-06-26
  • 打赏
  • 举报
回复
牛逼题目...
hezhixiongbei2 2011-10-21
  • 打赏
  • 举报
回复
C语言实现:
#include <stdio.h>

int main()
{
double total = 3000; /* 煤总量为3000吨 */
double once = 1000; /* 一次运输煤1000吨 */
double road = 1000; /* 路的长度为1000千米 */
double leavings = total;/* 剩余煤炭 */
double zuiJia; /* 从一个地点运到另一个地点后最佳剩余的煤总数 */
double result; /* 记录结果 */
int i;

double address[2];
int chiShu[2];

for(i = 0; i < 2; i++) {
chiShu[i] = (leavings / once * 2 -1);
zuiJia = leavings - ((leavings / once - 1 ) * once);
address[i] = zuiJia / chiShu[i];
leavings = (leavings / once - 1 ) * once;
printf("address[%d] = %f \n", i, address[i]);
}


result = total - address[0] * chiShu[0] - address[1] * chiShu[1] - (road - address[0] - address[1]);

printf("result leavings = %6.2f \n", result);
return 0;
}
输出答案是:533.33
shenyan008 2011-10-12
  • 打赏
  • 举报
回复
[Quote=引用 40 楼 mycolorful 的回复:]

引用 38 楼 changshuaia 的回复:
这是一个路程最优化问题,答案应该是533.333....吧
因此我们为了利益最大化,要保证每次火车运煤的时候,必须要满载。
因此步骤应该是:
首先运到200米处,剩2000吨煤
再次运到1000/3米处,剩1000吨煤
最后运到目的地,剩533.333吨煤
我算来也是这个数, 但是不清楚的是你的逻辑是怎么来的?
我的算法是:
C……
[/Quote]
学习,确实这个分阶段保留煤的运的比较多。
hondely 2011-10-11
  • 打赏
  • 举报
回复
差不多可以结贴了,答案都出来了,再留几天吧,让你们多看下
  • 打赏
  • 举报
回复
已经整理到博客 火车运煤,驴子吃萝卜,骆驼吃香蕉

最后,我想说一句很早就想说的话:

楼主,你才山西煤老板,你们全家都山西煤老板!!!
  • 打赏
  • 举报
回复
紧急修正上文,这就是上班偷偷泡论坛的坏处!![Quote=引用 155 楼 stone688598 的回复:]
最大需要的运输能力的方式Tmax=X/1000 * 2 - 1
那么能够运输的最大能量 = 1000 * (1/3 + 1/5 + ... + 1/7)
用归纳法很容易证明此结论。

又因为1/3+1/5+...1/7是发散的,所以理论上可以运送任意初始能源X,但是考虑到单程最大能力为1000,所以只要X比1000多一点,就可以用T3方式先运送一点,剩余采用T1,因此,约束条件为X > 1000.[/Quote]修改两点:
1)运输的最大能量 = 1000 * (1/3 + 1/5 + ... + 1/Tmax)
2)1/3+1/5+/7+......无穷是发散的,
  • 打赏
  • 举报
回复
[Quote=引用 144 楼 stone688598 的回复:]
以成本5消耗1000吨,最远可以走200米,此时剩余2000吨,也就是x=200
以成本3消耗1000吨,最远可以走333米,此时剩余1000吨,也就是y=333
此时距终点z=1000-(200+333)米,因此到达终点后,因此最多可剩余200+333=533吨

16楼给出了这个解法。这里数学化一下比较好。
[/Quote]说理方面还是欠缺一点,下面补充证明这种解是最优的。

有三种运输方式,分别是成本为5,成本为3,成本为1. 下面简称T5,T3,T1.

首先给出最优策略1:用完所有能源,也就是运到终点的能源 + 路上消耗的能源=3000。否则,不论在剩余多少能量,我们总可以后退一点,再多装一些,按照三种运输方式之一,把剩余能量的中的一部分运送到终点。

下面引入运输能力这个概念:
以T3举例,从起点向终点方向走2趟,最大可装载2000,运到距离为delta的某点之后,最大剩余2000-delta,因此称T3的运输能力C3 = 2000-delta <= 2000,(delta >= 0)。也就是说,T3最多能运送不超过2000的能量,超过2000就有剩余能量.
同理T5的运输能力C5 = 3000-delta <= 3000,T1的运输能力C1 = 1000 - delta <= 1000.

这样,我们就得出最优策略2:在运输能力范围内,选用成本最低的方式。如果用R表示剩余未被运输的能量,这样由策略1和策略2可知,采用的最优的运送方式
2000 <= R <= 3000, 采用T5方式
1000 <= R <= 2000, 采用T3方式
0 <= R <= 1000, 采用T1方式

即,先用T5消耗1000,剩余2000之后用T3方式再消耗1000,最后用T1方式运输余下能量。因此最优解为:
T5: 运输距离 x = 1000/5 = 200
T3: 距离 y = 1000/3 = 333.333
T1: 运输距离 z =1000 - x - y = 466.667
运送到终点的最大能量 = 1000 - 466.667 = 533.333

证毕.

近一步推广:
首先简化上面的计算过程:
最大能量 = 1000 - z = 1000 - (1000 - x - y) = x + y = 1000 * (1/3 + 1/5).
按照最优策略1和2可得出应该采用的运送方式:(假设X可被1000整除,否则可以同理做推广)

最大需要的运输能力的方式Tmax=X/1000 * 2 - 1
那么能够运输的最大能量 = 1000 * (1/3 + 1/5 + ... + 1/7)
用归纳法很容易证明此结论。

又因为1/3+1/5+...1/7是发散的,所以理论上可以运送任意初始能源X,但是考虑到单程最大能力为1000,所以只要X比1000多一点,就可以用T3方式先运送一点,剩余采用T1,因此,约束条件为X > 1000.
hondely 2011-10-11
  • 打赏
  • 举报
回复
换汤不换药啊
shuoshuo_mt 2011-10-11
  • 打赏
  • 举报
回复
煤老板弄了辆走1000公里能装3000吨不烧煤的车,直接拉过去了。
  • 打赏
  • 举报
回复
[Quote=引用 161 楼 dmcxnoface 的回复:]
1000*(1/3+1/5+1/7+……1/(2n+1))=1000
解得n=7
即初始要7*1000=7000吨。
[/Quote]嘿嘿,2n-1
西方惨败 2011-10-11
  • 打赏
  • 举报
回复
[Quote=引用 160 楼 stone688598 的回复:]

哈哈哈,提个问题,如果希望能够卖到集市上1000吨煤,那么最需要初始有多少吨?
[/Quote]

1000*(1/3+1/5+1/7+……1/(2n+1))=1000
解得n=7
即初始要7*1000=7000吨。
yean0206 2011-10-11
  • 打赏
  • 举报
回复
[Quote=引用 86 楼 0153 的回复:]

没人上代码我来上一个带详细步骤的:
C/C++ code
#include "stdafx.h"
typedef struct tagDepot {
double fStart;//距起点多少公里.
double fDepot;//存放多少货物.
double fDepotOneTimes;//每次补给多少货物.
} DEPOT,*P_DEPOT;

stati……
[/Quote]

还是这个V5
hondely 2011-10-11
  • 打赏
  • 举报
回复
[Quote=引用 107 楼 binbin0357 的回复:]

共计有3个中转站!
第1个中转站距离起点:333公里
全部煤炭到达1个中转站后,煤炭剩余总量:2000
第2个中转站距离起点:833公里
全部煤炭到达2个中转站后,煤炭剩余总量:1000
第3个中转站距离起点:1000公里
全部煤炭到达3个中转站后,煤炭剩余总量:833
到达目的地后,煤炭剩余总量:833
[/Quote]

第二步 要算来回的,你没算,一下最多可以运送1000的
  • 打赏
  • 举报
回复
哈哈哈,提个问题,如果希望能够卖到集市上1000吨煤,那么最需要初始有多少吨?
hondely 2011-10-11
  • 打赏
  • 举报
回复
[Quote=引用 154 楼 yean0206 的回复:]

引用 86 楼 0153 的回复:

没人上代码我来上一个带详细步骤的:
C/C++ code
#include "stdafx.h"
typedef struct tagDepot {
double fStart;//距起点多少公里.
double fDepot;//存放多少货物.
double fDepotOneTimes;//每次补给多少货物.
} DEPOT,*P……
[/Quote]

还是这个v5,顶下
hondely 2011-10-11
  • 打赏
  • 举报
回复
[Quote=引用 157 楼 stone688598 的回复:]

已经整理到博客 火车运煤,驴子吃萝卜,骆驼吃香蕉

最后,我想说一句很早就想说的话:

楼主,你才山西煤老板,你们全家都山西煤老板!!!
[/Quote]
哈哈,晕了,我可是正宗的单身程序员
zscedu 2011-10-10
  • 打赏
  • 举报
回复
学习,接分
chengmin_prime 2011-10-10
  • 打赏
  • 举报
回复
好帖 果断收藏··
演地 2011-10-10
  • 打赏
  • 举报
回复
超载表示无压力........
xiaohai0504 2011-10-10
  • 打赏
  • 举报
回复
这类题真扯淡,半路装卸煤也需要巨大的成本啊。现实是这样,煤老板要哭了。^^|
加载更多回复(146)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧