题解 P1016 【旅行家的预算】
题解 P1016 【旅行家的预算】
这是本蒟蒻的第一篇题解呢,,,心里有些小激动,希望dalao们不喜勿喷,不好的地方望谅解/(^o^)/~
(说实话我借用了楼下dalao的思路= =)
下面切入正题======================
本题需要贪心的思想,配合上递归
首先,在进行贪心之前可以先预判: 如果上一站到本站油箱中的油全用完也到不了本站,那么一定无解,直接"No Solution"(下面代码里有)
其次,我们贪心的策略是:当找到比之前的油更便宜的油站时就把原来的油替换,即一直加便宜的油那么会有两种情况:
1.如果我们的目的地des还没到达则继续开车(有点怪= =)
2.如果我们到达了目的地des,向后找到第一个比当前油价更低的油站,这时有两个选择
(1):我们如果能到达这个油更便宜的油站
(如果这时油不足则加够到达油价更小的油站的油) 将我们的目的地更新为这个更便宜的油站
(2):我们如果到不了这个更便宜的油站
我们向后找到如果加满油后能到达的最远油站,则加满油同时更新目的地des为加满后能到的最远油站
=========思路与代码分割线==========
好了,大概思路就是这样,下面贴代码:
#include<iostream>
#include<cstdio>
using namespace std;
struct station{
double di,pi;
}m[10005];//定义油站结构体
int n;
double d1,c,d2,ans,s;
//如题,ans为钱数,s为油箱中的实际油数
double solve(int des,int now)
//des表示目的地 _(destination)_ ,now表示当前所在油站
{
if(now==n+1)
//如果接下来没有油站则输出最小费用
{
printf("%.2lf",ans);
//按照格式输出.2lf
return 0;
}
if(now<des)
//如果当前还没到目的地des
{
s-=(m[now+1].di-m[now].di)/d2;
//把油加到正好够到下一个油站的
solve(des,now+1);
//从下一个油站继续行驶
return 0;
}
if(now==des)
//如果到了目的地des
{
int k=now+1;
while(m[k].pi>m[now].pi)k++;
//找到第一个当前位置之后油价更小的油站
if(m[k].di-m[now].di<=d2*c)
//如果能到达这个油价更小的油站
{
if(s<(m[k].di-m[now].di)/d2)
//如果这时油不足则加够到达油价更小的油站的油
{
ans+=((m[k].di-m[now].di)/d2-s)*m[now].pi;
s=(m[k].di-m[now].di)/d2;
//加上钱数同时更新油
}
solve(k,now);
//从当前向油价更小的油站进发
return 0;
}
else//到不了这个油价更小的油站的话
{
int u=now+1;
while(m[u].di-m[now].di<=d2*c)u++;
//我们找到加满油后能到达的最远油站
u--;
//去这个油站(同时加满油)
ans+=(c-s)*m[now].pi;
//加上钱数(加满)
s=c;
//更新油箱(油加满)
solve(u,now);
//从当前开始向这个最远油站进发
return 0;
}
}
}
int main()
{
cin>>d1>>c>>d2>>m[0].pi>>n;
//各种读入如题(注意初始化起点的油价p0)
for(int i=1;i<=n;i++)
{
cin>>m[i].di>>m[i].pi;
//每个油站的距离与油价
if(m[i].di-m[i-1].di>d2*c)
//如果当前站到上一站的距离油都用完还到不了则无解
{
printf("No Solution");
return 0;
}
}
m[n+1].di=d1;m[n+1].pi=0;
//初始化最后的终点(距离为d1,油价为0)
if(m[n+1].di-m[n].di>d2*c)
//如果倒数第一个油站也到不了终点则无解(同上)
{
printf("No Solution");
return 0;
}
solve(0,0);//其余的情况一定有解,接下来求解
return 0;//完毕,万事大吉!
}
然后。。。就没了。。(逃
悠远的天空,苍穹的尽头

浙公网安备 33010602011771号