贮油点问题(C语言)

描述 Description   

         一辆重型卡车欲穿过S公里的沙漠,卡车耗汽油为1升/公里,卡车总载油能力为W公升。显然卡车装一次油是过不了沙漠的。因此司机必须设法在沿途建立若干个贮油点,使卡车能顺利穿过沙漠。试问司机如怎样建立这些贮油点?每一贮油点应存储多少汽油,才能使卡车以消耗最少汽油的代价通过沙漠?

输入格式 Input Format

        仅一行,读入整数S,W(S<=1000,W<=500)。

输出格式 Output Format      

        编程计算及打印建立的贮油点序号,各贮油点距沙漠边沿出发的距离以及存油量(输出到小数点后第二位)。

样例输入 Sample Input

1000 500

样例输出 Sample Output

0      0.00   3881.36

1     22.43   3500.00

2     60.89   3000.00

3    106.35   2500.00

4    161.90   2000.00

5    233.33   1500.00

6    333.33   1000.00

7    500.00    500.00

 这道题可能有很多人一开始看不懂题目的意思,所以有必要先声明一下:

  就是说一辆车子想要穿过沙漠,但是一次肯定肯定通过不了,因为油箱的油是不够的,所以我们需要在沿途建立一系列贮油点,注意,汽车边通过  贮油点也是边建立的。

  就比如说样例:沙漠全长1000km,油箱容量为500L。输出就是说我们首先在起点(标号为0)建立一个3881.36L的贮油点,接下来我们将在距离起点22.43千米的位置(标号为1)建立一个含有3500L油的贮油点,一共跑了17次单程,消耗了381.36L的油,前一个(起点)贮油点的油已经全运过来了,然后把剩下的3500L油运向下一个贮油点......直到最后一个贮油点剩余500L油,油箱一次加满刚好跑完剩下的500km。

可见,车子是边走边建立储油点的,车子离开的时候,每个储油点的油都被运到了下一个储油点,到最后车子离开沙漠,油全部用完。我们要求的就是每个贮油点的信息。(消耗最少汽油的代价通过沙漠)

解题思路:

  如果从起点出发顺推,则我们无法确定第一个贮油点的位置及贮油量,因此我们可以用倒推法来解决这个问题:先从终点出发倒推最后一个储油点的位置及储油量,然后再把最后一个储油点作为终点,倒推倒数第二个储油点的位置及储油量。

  就拿样例来说,如果从头向后遍历的话,用DP不可行,因为没有说明其单位长度,而且DP的复杂度过高,所以从后向前考虑。在最优条件下,应该是卡车在前500米用光所有的油,然后在500米处灌满500L,再跑完剩下的500米,这样保证了最后消耗最少的汽油通过沙漠。所以目前明确在距离终点500米处要建一个500L的储油点。假设这个储油点左边X公里有一个储油量无限大的储油点,从此储油点不断搬运,使得这个500米处的储油点具有500L。那么以最优条件下,需要向储油点灌两次油,因为一次是肯定运不到这么多的。第一次:灌500-2xL的油(因为灌完要回来);第二次:灌500-xL的油(灌满就不用管了),求得x=500/3。可知跑的这两次一共灌了1000L油(灌满油箱两次),所以在距离终点500+500/3km的位置需要修建1000L的储油点。以此向前递推,直到到达起始点。

代码实现如下:

#include<bits/stdc++.h>
using namespace std;
double dis[1010],gas[1010],last,w;
int s,cnt,x;
int main()
{
    cin>>s>>w;
    dis[1]=s-w;
    gas[1]=w;
    last=dis[1];cnt=1;x=1;
    while(last!=0)
    {
        cnt++;
        x+=2;
        dis[cnt]=dis[cnt-1]-w/x;
        gas[cnt]=gas[cnt-1]+w;
        last=dis[cnt];
        if(last<0)
        {
            cnt--;break;
        }
    }
    dis[cnt+1]=0; 
    gas[cnt+1]=dis[cnt]*(x+2)+gas[cnt];//最后一次手动处理(起点) 
    for(int i=cnt+1;i>=1;i--)printf("%d	%.2lf	%.21lf	
",cnt-i+1,dis[i],gas[i]);
    return 0;
} 
原文地址:https://www.cnblogs.com/Mingusu/p/11839222.html