深搜题(如何找到进入下一层深搜的条件)
如今许多普通百姓家有了私家车,一些人喜爱自己驾车从一个城市到另一个城市旅游。自己驾车旅游时总会碰到加油和吃饭的问题,在出发之前,驾车人总要想方设法得到从一个城市到另一个城市路线上的加油站的列表,列表中包括了所有加油站的位置及其每升的油价(如 3.25 元/L)。驾车者一般都有以下的习惯:
- 除非汽车无法用油箱里的汽油达到下一个加油站或目的地,在油箱里还有不少于最大容量一半的汽油时,驾驶员从不在加油站停下来;
- 在每一个停下的加油站总是将油箱加满;
- 在加油站加油的同时,买快餐等吃的东西花去 20 元。
- 从起始城市出发时油箱总是满的。
- 加油站付钱总是精确到 0.1 元(四舍五入)。
- 驾车者都知道自己的汽车每升汽油能够行驶的里程数。
现在要你帮忙做的就是编写一个程序,计算出驾车从一个城市到另一个城市的旅游在加油和吃饭方面最少的费用。
输入格式
第一行是一个实数,是从出发地到目的地的距离(单位:km)。
第二行是三个实数和一个整数,其中第一个实数是汽车油箱的最大容量(单位:L);第二个实数是汽车每升油能行驶的公里数;第三个实数是汽车在出发地加满油箱时的费用(单位:元);一个整数是 1 到 50 间的数,表示从出发地到目的地线路上加油站的数目。
接下来 n 行都是两个实数,第一个数表示从出发地到某一个加油站的距离(单位:km);第二个实数表示该加油站汽油的价格(单位:元)。
数据项中的每个数据都是正确的,不需判错。一条线路上的加油站根据其到出发地的距离递增排列并且都不会大于从出发地到目的地的距离。
输出格式
输出一个实数,即精确到 0.1 元的最小的加油和吃饭费用。
输入输出样例
输入 #1复制
600 40 8.5 128 3 200 3.52 350 3.45 500 365
输出 #1复制
13133.2
//我以为自己能写开这道题的,实际上写的时候也被难住了,难在了哪呢?dfs函数实现上,我没找到在同一深度时有什么不同选择项,感觉是个线性题,实则不然,只是我没从题目中提取出来罢了,看条件一,有种情况,油不够到下一个加油站那必定加油,否则再细分,若油超过1/2,就选择不加,到现在为止是否感觉还是线性的?但如果油不够1/2时便会出现两个选择项了,停下来加油或者不停,想到这层就好写了
//奉上代码
#include <bits/stdc++.h>
using namespace std;
struct stn
{
double loc;
double prc;
};
stn gas[64];
int dis, n;
double vol, per, cst, ans;
bool flg = true;
void dfs(double ful, int loc, double sum){
if(loc == n + 1){
if(flg){
ans = sum;
flg = false;
}
else if(sum < ans){
ans = sum;
}
return;
}
if((gas[loc + 1].loc - gas[loc].loc) / per > ful){
sum += 20;
sum += gas[loc].prc * (vol - ful);
ful = vol;
ful -= (gas[loc + 1].loc - gas[loc].loc) / per;
dfs(ful, loc + 1, sum);
}
else if(ful < vol / 2){
dfs(ful - (gas[loc + 1].loc - gas[loc].loc) / per, loc + 1, sum);
sum += 20;
sum += gas[loc].prc * (vol - ful);
ful = vol;
ful -= (gas[loc + 1].loc - gas[loc].loc) / per;
dfs(ful, loc + 1, sum);
}
else{
ful -= (gas[loc + 1].loc - gas[loc].loc) / per;
dfs(ful, loc + 1, sum);
}
}
int main(int argc, char const *argv[])
{
scanf("%d", &dis);
scanf("%lf %lf %lf %d", &vol, &per, &cst, &n);
for(int i = 1; i <= n; i ++)
scanf("%lf %lf", &gas[i].loc, &gas[i].prc);
gas[n + 1].loc = dis;
gas[0].loc = 0;
dfs(vol, 0, 0);
printf("%.1lf", ans + cst);
return 0;
}