Loading

【题解】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;
}
posted @ 2025-12-12 23:38  Seqfrel  阅读(0)  评论(0)    收藏  举报