洛谷P1016 旅行家的预算

传送门:>Here<

一个旅行家想开车以最少的费用从一个城市到另一个城市(出发时油箱是空的)。给定两个城市之间的距离\(D_1\)、汽车油箱的容量\(C\)(单位:升)、每升汽油能行驶的距离\(D_2\)、出发点每升汽油价格\(P\)和沿途油站数\(N\),油站ii离出发点的距离\(D_i\)、每升汽油价格\(P_i\)如果无法到达目的地,则输出“No Solution”。

解题思路

吃完饭来写

/*DennyQi 2019*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N = 100010;
const int P = 998244353;
const int INF = 0x3f3f3f3f;
inline int mul(const int& a, const int& b){ return 1ll*a*b%P; }
inline int add(const int& a, const int& b){ return (a+b>=P)?a+b-P:a+b; }
inline int sub(const int& a, const int& b){ return (a-b<0)?a-b+P:a-b; }
inline int read(){
    int x(0),w(1); char c = getchar();
    while(c^'-' && (c<'0' || c>'9')) c = getchar();
    if(c=='-') w = -1, c = getchar();
    while(c>='0' && c<='9') x = (x<<3)+(x<<1)+c-'0', c = getchar(); 
    return x*w;
}
struct Gas{ int idx; double v; }q[N];
int n,h,t;
double D1,C,D2,d[N],p[N],W,ans,dis;
int main(){
    // freopen("file.in","r",stdin);
    scanf("%lf%lf%lf%lf%d",&D1,&C,&D2,&p[0],&n);
    for(int i = 1; i <= n; ++i){
        scanf("%lf%lf",d+i,p+i);
    }
    d[n+1] = D1;
    h = 1, t = 1;
    q[t].idx = 0;
    q[t].v = C;
    W = C;
    ans = C * p[0];
    for(int i = 1; i <= n+1; ++i){
        dis = d[i] - d[i-1];
        while(h <= t && q[h].v * D2 < dis){
            dis -= q[h].v * D2;
            W -= q[h].v;
            ++h;
        }
        if(dis > 0 && h > t){
            printf("No Solution\n");
            return 0;
        }
        else{
            q[h].v -= dis / D2;
            W -= dis / D2;
        }
        while(h <= t && p[i] <= p[q[t].idx]){
            W -= q[t].v;
            ans -= q[t].v * p[q[t].idx];
            --t;
        }
        q[++t].idx = i;
        q[t].v = C-W;
        ans += q[t].v * p[i];
    }
    while(h <= t){
        ans -= q[t].v * p[q[t].idx];
        --t;
    }
    printf("%.2f\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/qixingzhi/p/11249272.html