zoukankan      html  css  js  c++  java
  • 贮油点问题(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;
    } 
  • 相关阅读:
    前端基础之BOM和DOM
    JavaScript
    css-属性、样式调节
    计算机操作系统
    计算机组成原理
    计算机基础之编程
    css-选择器
    HTML-标签
    python打印有色字体
    mysql 数据库语法详解
  • 原文地址:https://www.cnblogs.com/Mingusu/p/11839222.html
Copyright © 2011-2022 走看看