问题描述
一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格P和沿途油站数N(N可以为零),油站i离出发点的距离Di、每升汽油价格Pi(i=1,2,……N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。
解题思路:
贪心规则:
从当前点开始,再c*d2的距离内,找第一个油价低于当前结点油价的站点
如果找到:
如果当前结点剩余油量可以抵达,更新下一个站点的剩余油量;
如果当前结点剩余油量不可以抵达,更新当前结点需要添加的油量;
如果找不到:
则在本站加满油,将相邻的结点当做下一个目的结点;-------》条件1
如果超过c*d2,则不可以到达;
需要注意的是:判断找没找到时候应当注意用目的结点与当前结点的差值<c*d2,判断。
如果单单用一个flag标志的话,当遇到最后一个结点,即目的地,你会直接跳到---》条件1---那个条件中,从而多加了油,使得结果偏大;
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
double dis;
double cost;
double has;
double add;
int id;
};
int main()
{
//freopen("test.txt","r",stdin);
double distance;
double c;
double v;
double scost;
int n;
node sta[10001];
node start;
scanf("%lf%lf%lf%lf%d",&distance,&c,&v,&scost,&n);
sta[0].dis=0;
sta[0].cost=scost;
sta[0].has=0;
sta[0].id=0;
sta[0].add=0;
sta[n+1].dis=distance;
sta[n+1].cost=100000000;
sta[n+1].id=n+1;
sta[n+1].has=0;
sta[n+1].add=0;
start=sta[0];
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&sta[i].dis,&sta[i].cost);
sta[i].has=0;
sta[i].id=i;
sta[i].add=0;
}
bool goal=true;
double ans=0;
while(start.id<n+1)
{
double len=c*v;
if(sta[start.id+1].dis-start.dis>len)
{
goal=false;
printf("No Solution\n");
break;
}
int flag=false;
int k=1;
while(k<=n)
{
if(sta[k].id>start.id&&sta[k].dis-start.dis<len&&sta[k].cost<=start.cost)
{
flag=true;
break;
}
k++;
}
if(sta[k].dis-start.dis<len)
{
if(start.has*v<sta[k].dis-start.dis)
{
start.add=(sta[k].dis-start.dis)/v-start.has;
start.has+=start.add;
sta[start.id]=start;
start=sta[k];
}
else
{
sta[k].has=start.has-(sta[k].dis-start.dis)/v;
start=sta[k];
}
}
else
{
k=start.id+1;
start.add=c-start.has;
start.has=c;
sta[start.id]=start;
sta[k].has=start.has-(sta[k].dis-start.dis)/v;
start=sta[k];
}
}
if(goal)
{
for(int i=0;i<=n;i++)
{
ans+=sta[i].add*sta[i].cost;
}
printf("%.2lf\n",ans);
}
}