一道题目《吉普车穿越沙漠问题》不知如何建模,大虾请指教
在高等教育出版社出版,张基温编写的《c++程序设计基础》一书70页有这样一道题目。
吉普车穿越沙漠问题
一辆吉普车来到1000km宽的沙漠边沿。吉普车的耗油量为1L/Km,总装油量为500L。显然,吉普车必须用自身油箱中设几个临时加油点,否则是通不过沙漠的。假设在沙漠边沿有充足的汽油可供使用,那末吉普车应在那些地方,建多大的临时加油点,才能以最少的油耗穿过这块沙漠?
小鸟我百思不得要领,请各位大虾不吝赐教!bow!
倒着推结合数学归纳法然后归纳出递推公式,实际上是数学题,不是编程题。
请看 http://www.Codefund.cn/expert/topic/975/975341.xml?temp=.6684992
只不过吉普车成了卡车
我看过了,问题确实一样,但是他们好像使用的pascal什么的,我看不懂,能否写出算法或者使c++程序,把思路说清楚也可以
一辆吉普车来到1000km宽的沙漠边沿。吉普车的耗油量为1L/Km,总装油量为500L。显然,吉普车必须用自身油箱中设几个临时加油点,否则是通不过沙漠的。假设在沙漠边沿有充足的汽油可供使用,那末吉普车应在那些地方,建多大的临时加油点,才能以最少的油耗穿过这块沙漠?
这个题目是用倒推法,我也是只看了看算法而已.因为我刚刚开始学习C,2个月水平有限,呵呵,先卖弄了.
从终点到起点1K公里.
我门从终点开始考虑,
也就是把终点到起点是:
I0……I1……I2……In
首先我们考虑是从I1到I0需要的油是500公升,也就是我门在I1的位置存放500公升的汽油才能保证车子到终点。
我门把两个I之间的距离写为S[i],耗油量为V[i];
这样第一步我们知道了I0……I1之间
S1=500公里,V1=500公升。
下一步,从I1……I2之间,我们必须至少要从I2处向I1开两趟车子(单向)才能保证I1处的储存量500公升。
这样因为我们是从I2开向I1处,所以,来回加(双向)在一起应该至少是3趟才能保证I1处有500公升的汽油。
能保证3次往返最低的耗油量就是500公升,
那么我们来求出3次往返的500公升耗油量的距离就是:S2=500 / 3。
I0……I2的距离就是:S1+S2=500+500/3
而同时在I2处的储存油量为:V2=500公升+500公升=1000公升
继续向下考虑,从I2……I3之间,保证I2处有1000公升的汽油,我门必须要卡车最少从I3向I2开3趟(单趟),来回就是5趟。路上的耗油量是500公升,也就是我门在I3处存放1500公升汽油。
那么我们来回的距离是:S3=500/5。
I0……I3的距离是:S1+S2+S3=500+500/2+500/3。
同时I3的储存油量是:1500公升。
由此推断:
如果需要i处储存油,那么要i*500的储存量。
车子从i+1到I处(单向)的至少要i次。加上返回的次数一共是2*i—1次。
而这2*i—1次的最小耗油量是500公升。
那么Si的距离就是500/(2*i—1)。
最后i=n到开始地点的
距离是1000-sum(Sn) (i为1、2、……求他们的和,也就是前面的总路程。)
储存油:n*500。
车子至少要从起点开n+1次满油到n处。加上返回的,一共是2n+1次。
我们2n+1次的耗油量是(1000-sum(Sn))*(2n+1)
[注:就是距离*往返次数=500和前面的500/往返次数=距离是一样的。]
我们起点的油量Vn+(1000-sum(Sn))*(2n+1)。
Vn就是从n点到终点I0总的需求油量。
******************************************************************************
打了半天的字辛苦死了,也不知道给不给些分哦。
模型自己写吧,程序如下:
用倒推法:
program oil_lib;
var
k:integer;
d,
dl:real;
oil,dis:array[1..10] of real;
i:integer;
begin
k:=1;
d:=500;
dis[1]=500;
oil[1]:=500;
repeat
k:=k+1;
d:=d+5002/(2*k-1);
dis[k]:=d;
oil[k]:=oil[k-1]+500;
until d>=1000;
dis[k]:=1000;
di:=1000-dis[k-1];
oil[k]:=d1*(2*k+1)+oil[k-1];
for i:=0 to k do
writeln(i,1000-dis[k-i]:30,oil[k-i]:80);
end.
lizhongkun(泛型) ( ) 信誉:97
哈哈哈
原来你PASCAL也能看懂啊
厉害厉害
你可以从简单一点的情形开始想起:
1、沙漠只有500公里或者更短,这时很简单,一次搞定。
2、沙漠600km,怎么办?我们需要保证的是:车到了离沙漠终点还有500km的地方,能恰恰加满油而且不
会有任何多余,好了,方案其实很简单,从起点处加300升油,这300升油怎么用呢:开出100km,存下100
升,剩下100升刚好使得汽车返回起点。再在起点处加满500升油,这时就可以一路狂奔了,当然,要记得
开了100公里后,把存放在那儿的100升油也加上。(这时在起点的油一共是500+300)
3、我们先看看2的情况,符合这种情况的沙漠的最大距离是多少呢:答案是(500+500/3)公里。即在起
点准备1000升油,第一次装500升,跑了500/3公里后存放500/3升油,然后返回起点,这时车里的油也正
好用完,然后再在起点处装500升,跑了500/3公里后,把车内的(500-500/3)升油先放下,然后再一次
性把500升油装入车中。一路跑吧。
4。当沙漠的距离超过了(500+500/3)km(但又超过得不多)又当如何?这时我们可以把前面的(500+
500/3)km看成一段整体,需要保证的是:在距离沙漠终点(500+500/3)km处恰恰有1000升油(由3的分
析可知)。怎么来保证呢,我们假设沙漠的距离只比(500+500/3)多了1公里,因为汽车的容量是500升
,所以1000升油最少从起点装3次油才能倒满(具体情况你可以自己想想)。除了3次装油,还有两次折回
,所以往返正好有5次,这5次的能保证的距离是500/5,所以这时我们又把沙漠的距离延伸到了:(
500+500/3+500/5),起点应该储备1500升油。
5。当沙漠的距离超过了(500+500/3+500/5)公里,我们要保证的是在距离沙漠终点(500+500/3+500/5
)公里的地方有1500升油。。。。。。。。
一路往下,总有某一个值使得fdis =(500+500/3+500/5+..+500/(2k-1))<1000,但是
(500+500/3+500/5+..+500/2k-1+500/(2k+1))>1000,应该在起点准备多少油呢?这时多了一小段出来
,很像情形2的分析了,说白了,在起点准备的油应当是:(1000 - fdis)*往返次数 + k*500。
源代码:
#include "stdafx.h"
#include <iostream>
using namespace std;
const float des = 1000 ;//沙漠长度
const float car = 500; //汽车耗油
int main()
{
float temp = 0;
for(int i = 0; temp < des; i++)
{
temp += car/(2*i + 1);
}
float *seg = new float[i]; //各个存储点距离终点的距离
float *oil = new float[i]; //这些点的存油量
seg[0] = car; //距离终点500公里处是一个存储点
oil[0] = car; //这点存油500升
//计算各个存储点离终点的距离和存油量
for(i = 0;seg[i] < des; i++)
{
seg[i+1] = seg[i] + car/(2*i + 3);
oil[i+1] = oil[i] + car;
}
//在起点处的一小段的存油量
seg[i] = des;
oil[i] = oil[i-1] + (des - seg[i-1])*(2*i + 1);
for (int j = 0;j<= i;j++)
{
cout<< seg[j] <<" "<<oil[j]<<endl;
}
delete[] seg;
delete[] oil;
return 0;
}
原来写过一个更一般的,找不到了。
你可以从简单一点的情形开始想起:
1、沙漠只有500公里或者更短,这时很简单,一次搞定。
2、沙漠600km,怎么办?我们需要保证的是:车到了离沙漠终点还有500km的地方,能恰恰加满油而且不会有任何多余,好了,方案其实很简单,从起点处加300升油,这300升油怎么用呢:开出100km,存下100升,剩下100升刚好使得汽车返回起点。再在起点处加满500升油,这时就可以一路狂奔了,当然,要记得开了100公里后,把存放在那儿的100升油也加上。(这时在起点的油一共是500+300)
3、我们先看看2的情况,符合这种情况的沙漠的最大距离是多少呢:答案是(500+500/3)公里。即在起点准备1000升油,第一次装500升,跑了500/3公里后存放500/3升油,然后返回起点,这时车里的油也正好用完,然后再在起点处装500升,跑了500/3公里后,把车内的(500-500/3)升油先放下,然后再一次性把500升油装入车中。一路跑吧。
4。当沙漠的距离超过了(500+500/3)km(但又超过得不多)又当如何?这时我们可以把前面的(500+500/3)km看成一段整体,需要保证的是:在距离沙漠终点(500+500/3)km处恰恰有1000升油(由3的分析可知)。怎么来保证呢,我们假设沙漠的距离只比(500+500/3)多了1公里,因为汽车的容量是500升,所以1000升油最少从起点装3次油才能倒满(具体情况你可以自己想想)。除了3次装油,还有两次折回,所以往返正好有5次,这5次的能保证的距离是500/5,所以这时我们又把沙漠的距离延伸到了:(500+500/3+500/5),起点应该储备1500升油。
5。当沙漠的距离超过了(500+500/3+500/5)公里,我们要保证的是在距离沙漠终点(500+500/3+500/5)公里的地方有1500升油。。。。。。。。
一路往下,总有某一个值使得fdis =(500+500/3+500/5+..+500/(2k-1))<1000,但是
(500+500/3+500/5+..+500/2k-1+500/(2k+1))>1000,应该在起点准备多少油呢?这时多了一小段出来,很像情形2的分析了,说白了,在起点准备的油应当是:(1000 - fdis)*往返次数 + k*500。
源代码:
#include "stdafx.h"
#include <iostream>
using namespace std;
const float des = 1000 ;//沙漠长度
const float car = 500; //汽车耗油
int main()
{
float temp = 0;
for(int i = 0; temp < des; i++)
{
temp += car/(2*i + 1);
}
float *seg = new float[i]; //各个存储点距离终点的距离
float *oil = new float[i]; //这些点的存油量
seg[0] = car; //距离终点500公里处是一个存储点
oil[0] = car; //这点存油500升
//计算各个存储点离终点的距离和存油量
for(i = 0;seg[i] < des; i++)
{
seg[i+1] = seg[i] + car/(2*i + 3);
oil[i+1] = oil[i] + car;
}
//在起点处的一小段的存油量
seg[i] = des;
oil[i] = oil[i-1] + (des - seg[i-1])*(2*i + 1);
for (int j = 0;j<= i;j++)
{
cout<< seg[j] <<" "<<oil[j]<<endl;
}
delete[] seg;
delete[] oil;
return 0;
}
ninesong,waterstony两位兄弟费心了,为实现承诺,我决定在非技术区内给两哥们每人散200分,如何,望回话!