类Runtime和火车运煤问题

1 类Runtime

每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。可以通过 getRuntime 方法获取当前运行时。

应用程序不能创建自己的 Runtime 类实例。

2 火车运煤问题

问题来源:http://coolshell.cn/articles/4429.html/comment-page-5#comments

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

假设运到集市的煤的重量为left,我们可以假设火车在某处捡了left吨煤,则该问题可转化为问题二:

条件:最大容量为capacity的火车,把煤运到pick_location处后,扔下left吨煤然后返回原地,刚好消耗掉min_coal吨煤。

问题一:根据left求min_coal。

问题二:根据min_coal求left。

问题一

我们先求取问题一

运left吨煤到集市,至少需要矿区煤的重量为min_coal = distance + min_coal(capacity, left, left)。

其中min_coal(capacity, pick_location, left)为问题一的解,表示最大容量为capacity的火车,把煤运到pick_location处后,扔下left吨煤然后返回原地,刚好消耗掉所有的煤的情况下,矿区的煤的最小重量min_coal。

1 left < 0时,min_coal = 0;

2 pick_location * 2 + left < capacity时,min_coal = pick_location * 2 + left

3 其他,min_coal = pick_location * 2 + min_coal(capacity, new_left/2, new_left)

其中new_left = pick_location * 2 + left - capacity,火车去时,在new_left/2处拿起new_left/2吨煤,然后在new_left处放下new_left吨煤,再在回来时,在new_left/2处拿起new_left/2吨煤。

根据该方案可求得:

left = 529时,矿区最少煤量为2989

即本题答案至少为529

问题二

对于问题二,假设矿区为A、集市为D,两者之间有两个点B、C可以存煤。

1 A区有煤3000吨,火车最大容量为1000,即需要从A出发三次,由于只有一列火车,需要回来二次。

2 B有煤2000吨,即需要从B出发二次,从C回到B一次。

3 C有煤1000吨,火车装满后直接奔赴D,只有一次。

即5AB=1000,3BC=1000,AB+BC+CD = 1000,即CD=7/15*1000,left = 8/15 * 1000=533

至于这里为何在B处和C处出发时为1000,是因为出发时装煤量为0~1000,而该线性问题,解为临界值,不可能为0,只能为1000。

求得结果后代入验证,发现533满足题意,即该题的解至少为533。

也即,如果min_coal的值发生变化,left的值也会变化

min_coal = 2000, left = 1000 * (1/3) = 1000 * 1/3

min_coal = 3000, left = 1000 * (1/3 + 1/5 = 1000 * 8/15

min_coal = 4000, left = 1000 * (1/3 + 1/5 + 1/7) = 1000 * 71/105

min_coal = 5000, left = 1000 * (1/3 + 1/5 + 1/7 + 1/9) = 1000 * 248 / 315

但当min_coal = 7000时,按此公式计算的left > 1,也即最后可以运1000以上的煤到集市,这时就过了临界值,需要用另一个公式了。

该思路对另一种情况也需要重新考虑,矿区煤量不为整千,如min_coal = 3400时。

 

扩展问题:

1 耗煤量与载媒量有关时。

2 矿区总媒量变化的情况。

 

问题一代码如下:

# 最大容量为capacity的火车,把煤运到distance处后,还剩下left吨煤。
# 返回值:煤的最小重量min_coal。
def train(distance, capacity, left): if(left < 0): return 0; if(left < distance/3): return distance + left * 3 return distance + min_coal(capacity, left, left) # 最大容量为capacity的火车,把煤运到pick_location处后,扔下left吨煤然后返回原地,刚好消耗掉所有的煤 # 返回值:煤的最小吨数min_coal。 def min_coal(capacity, pick_location, left): print "pick_location", pick_location print "left: ", left if(left < 0): return 0 if(pick_location * 2 + left < capacity): return pick_location * 2 + left new_left = pick_location * 2 + left - capacity # 需要在路上捡new_left吨煤,最少得在new_left处捡 new_pick_location = new_left / 2 return pick_location * 2 + min_coal(capacity, new_pick_location, new_left)

  

posted @ 2014-07-07 22:42  yanyichao  阅读(291)  评论(0编辑  收藏  举报