• <基础训练>旅行家的预算(贪心算法)


    问题描述

      一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格P和沿途油站数N(N可以为零),油站i离出发点的距离Di、每升汽油价格Pi(i=1,2,……N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。

    输入格式

      第一行为4个实数D1、C、D2、P与一个非负整数N;
      接下来N行,每行两个实数Di、Pi。

    输出格式

      如果可以到达目的地,输出一个实数(四舍五入至小数点后两位),表示最小费用;否则输出“No Solution”(不含引号)。

    样例输入

    275.6 11.9 27.4 2.8 2
    102.0 2.9
    220.0 2.2

    样例输出

    26.95

    思路:是找在最大行驶距离内寻找比当前便宜的加油站,然后判断是否能一次到达,不能的话先加满,然后一个一个判断直到剩下的油量不足到下一个加油站就加油,加适量。

    于是有以下2 situations:
    
    1.这个站点j 就是pos 
      再细分两种情况:
        1.从pos就可以走到终点
          于是我们把油加到刚好到达终点即可
             cost += ((d[i] - d[pos]) / d2 - remain)*p[pos];就得到了最后答案。
              remain是当前剩余的油
        2.从pos不能一把走到终点
          于是,从当前位置走,走到哪里加油都不够在pos这里加油划算。
          所以加满。
    2.这个站点j 是在pos后面的某个站点
      也有两种情况
        1.当前剩余的油remain不够走到j
          于是我们,把油加来刚好能够走到j就行了。(因为j这里好好便宜!)
        2.剩余的油remain足够,直接开过去就行了。
    
    ########具体操作见如下代码

    #include  
    #include  
    #include  
    using namespace std;
    double d[10000], p[10000];   //出发点每升汽油的价格p
    int main()
    {
    	ios::sync_with_stdio(false);  //取消cin在stdin上的同步,增加cin的读取效率
    	double d1, c, d2;  
    	int n;   //沿途油站数目
    	cin >> d1 >> c >> d2 >> p[0] >> n;
    	d[n + 1] = d1;   //第n个油站后即为最后的站点
    	for (int i = 1; i <= n; i++)  //输入每一个油站离出发点的距离以及每个站点汽油的价格
    	{
    		cin >> d[i] >> p[i];
    	}
    	int pos = 0;
    	double remain = 0, cost = 0;
    	do
    	{
    		bool found = false;   //判定能不能到达
    		for (int i = pos + 1; i <= n + 1 && d[i] <= d[pos] + c*d2; i++) //循环判断加满油能不能到达下一个加油站
    		{
    			if (p[i] < p[pos])   //判断下个站点汽油的价格是不是比这个pos站点汽油的价格小
    			{
    				if (d[pos] + remain*d2 >= d[i])  //若是剩余的油足够,刚好开过去
    				{
    					remain -= (d[i] - d[pos]) / d2;    //剩余的油减少,减少量就是从一个站点到下一个站点用到的油
    				}
    				else  //剩余的油不够
    				{
    					cost += ((d[i] - d[pos]) / d2 - remain)*p[pos];  //还需要加的油花费的价钱,不用加满
    					remain = 0;   //到达下一个站点恰好没油了,所以剩余汽油量清0
    				}
    				pos = i;
    				found = true;
    				break;
    			}
    		}
    		if (!found)
    		{
    			cost += (c - remain)*p[pos];  //不能到达前花费了多少钱
    			remain = c - (d[pos + 1] - d[pos]) / d2;     //还剩多少油
    			if (remain >= 0) pos++;  //小于0,油根本不够到达下一个站点,大于0,代表可以去下一个加油站
    			else
    			{
    				cout << "No Solution";
    				return 0;
    			}
    		}
    	} while (pos <= n);  //循环条件:没到达终点
    	cout.setf(ios::fixed);  //以定点形式显示浮点数
    	cout << setprecision(2) << cost;
    }
  • 相关阅读:
    转化限制+分析变量变化引起的答案变化:Gym - 104065D
    一幅长文细学Spring(二)——IOC
    jwt(json web token)
    mongodb如何删除数据并释放空间
    嵌入式养成计划-34--函数库
    nm命令使用详解,让你加快学习速度
    基于Android的日程管理工具
    Spring循环依赖
    【信号处理】基于CNN自编码器的心电信号异常检测识别(tensorflow)
    智慧工地安全管理大屏UX/UI设计的触控感——从交互体验角度的产品思考
  • 原文地址:https://blog.csdn.net/G11176593/article/details/128175794