【题解】P1016 旅行家的预算
题面
前言
很古老的搜索典题力!
正文
其实就是更新参数……
以及一个可行性剪枝
代码实现:
注意到给的 \(D_i\) 是没法直接用的,差分处理
设置三元组 \((x,y,z)\) 为参数,分别表示处理到第 \(x\) 个加油站,当前油量 \(y\),当前花费 \(z\)
然后初始从 \((0,0,0)\) 开始搜索,简单拓展即可
答案取所有可行方案的最小值
可行方案的边界条件为 \(x==n+1\)
最后注意浮点数运算即可,以及输出控制两位小数!
代码
#include<iostream>
#include<iomanip>
using namespace std;
int const maxn=512;
int n;
bool flag;
double ans=2147483647,sum,c,dis;
double D[maxn],p[maxn],d[maxn];
inline void dfs(int st,double oil,double cost){
if(st==n+1){
if(cost<ans)ans=cost;
flag=1;
return;
}
if(c*dis<d[st])return;
double tot=0;
for(int i=st;i<=n;i++){
tot+=d[i];
if(dis*c<tot)break;
dfs(i+1,c-tot/dis,cost+p[st]*(c-oil));
dfs(i+1,0,cost+max((double)0,p[st]*tot/dis-p[st]*oil));
}
return;
}
int main(){
cin>>sum>>c>>dis>>p[0]>>n;
for(int i=1;i<=n;i++){
cin>>D[i]>>p[i];
d[i-1]=D[i]-D[i-1];
}
d[n]=sum-D[n];
dfs(0,0,0);
if(flag){
cout<<fixed<<setprecision(2)<<ans<<endl;
}else{
cout<<"No Solution"<<endl;
}
return 0;
}
后记
眼前你,化为泡影……
完结撒花!