【题解】Luogu P1016 [NOIP 1999 普及组/提高组] 旅行家的预算
思路
与 P9749 [CSP-J 2023] 公路 颇为类似。
很显然的贪心:要在油费少的加油站加更多油。
模拟驾驶顺序:从 \(0\) 点出发,寻找油费低的加油站。如果能开到一个油费比当前点还低的站,那就加到刚好开到那一站的油,后面的路程用新加油站的油一定更优;如果开不到,那就找一个能开到的油费最低的站加油,但因为新站不优于本站,我们要让尽可能多的路程用本站的油,所以此次要加满,除非还未加满就到达了终点。
虽然思路很好想,但是模拟过程非常繁杂,要计算很多乱糟糟的式子并判断很多特殊情况。而且据说数据很水,我也不知道我的做法究竟是否正确。
实现
#include<bits/stdc++.h>
using namespace std;
int n,lst;
double s,c,l;
double dis,fue,ans;
double d[10],p[10];
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>s>>c>>l>>p[0]>>n;
for(int i=1;i<=n;i++) cin>>d[i]>>p[i];
for(int i=0;i<n;i++){
int flag=1;
double minp=510,t,tar,tfue;
for(int j=i+1;j<=n;j++){
if((d[j]-d[i])/l>c) break;
else flag=0;
if(p[j]<p[i]){
ans+=((d[j]-d[i])/l-fue)*p[i];
fue=0;
i=j-1;
flag=2;
break;
}
if(p[j]<minp){
minp=p[j];
t=min((c-fue),(s-d[i])/l)*p[i];
tfue=min(c,fue+(s-d[i])/l)-(d[j]-d[i])/l;
tar=j;
flag=3;
}
}
if(flag==1){
cout<<"No Solution";
return 0;
}else if(flag==3){
ans+=t;
i=tar-1;
fue=tfue;
}
}
if((s-d[n])/l>c) cout<<"No Solution";
else{
ans+=((s-d[n])/l-fue)*p[n];
cout<<fixed<<setprecision(2)<<ans;
}
return 0;
}

浙公网安备 33010602011771号