【题解】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;
}

后记

眼前你,化为泡影……

完结撒花!

posted @ 2024-12-23 19:25  sunxuhetai  阅读(46)  评论(0)    收藏  举报