P1016 旅行家的预算
看到这个数据范围,本蒟蒻马上就想到了搜索 毕竟万物皆可搜索嘛
所有的加油站和起点终点都是在一条直线上的,我们可以把它们看做
对于搜索函数,我们传入三个量,分别为该节点的编号,当时的油量和当时的花费。我们从该节点开始枚举节点
void get(int x,double s,double m)//分别表示编号、油量和花费
{
if(s<0 || s>c)
return ;//若油箱的油不符合实际,则返回
if(x==n+1)
{
ans=min(ans,m);
return ;
}//到达终点则更新答案
for(int i=x;i<=n+1 && (cn[i][0]-cn[x][0])/d2<=c;i++)
if((cn[i][0]-cn[x][0])/d2<=s)
get(x+1,s-(cn[x+1][0]-cn[x][0])/d2,m);//若到达节点i所需的油比当前的油还少,则不用加油
else
get(x+1,(cn[i][0]-cn[x][0])/d2-(cn[x+1][0]-cn[x][0])/d2,m+((cn[i][0]-cn[x][0])/d2-s)*cn[x][1]);//若当前的油不够开到节点i,则加到刚好可以开到
get(x+1,c-(cn[x+1][0]-cn[x][0])/d2,m+(c-s)*cn[x][1]);//加满油箱
}
最后说一下输出,题目要求是四舍五入保留两位小数输出,但经过本蒟蒻的试验,四舍五入是不行的,直接输出即可(为何如此毒瘤),用printf方便又快捷:
if(ans==INF)//若没有更新答案说明不能到达终点
cout<<"No Solution";
else
printf("%.2lf",ans);
好了,最后上一下完整的代码:
#include<iostream>
#include<cstdio>
using namespace std;
double d1,c,d2,p,ans=1e6,cn[10][2];
int n;
void get(int x,double s,double m)
{
if(s<0 || s>c)
return ;
if(x==n+1)
{
ans=min(ans,m);
return ;
}
for(int i=x;i<=n+1 && (cn[i][0]-cn[x][0])/d2<=c;i++)
if((cn[i][0]-cn[x][0])/d2<=s)
get(x+1,s-(cn[x+1][0]-cn[x][0])/d2,m);
else
get(x+1,(cn[i][0]-cn[x][0])/d2-(cn[x+1][0]-cn[x][0])/d2,m+((cn[i][0]-cn[x][0])/d2-s)*cn[x][1]);
get(x+1,c-(cn[x+1][0]-cn[x][0])/d2,m+(c-s)*cn[x][1]);
}
int main()
{
cin>>d1>>c>>d2>>p>>n;
for(int i=1;i<=n;i++)
cin>>cn[i][0]>>cn[i][1];
cn[0][1]=p,cn[n+1][0]=d1;//初始化
get(0,0,0);//从起点开始搜索
if(ans==1e6)
cout<<"No Solution";
else
printf("%.2lf",ans);
return 0;
}