[Luogu] P1016 旅行家的预算

题目描述

一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格P和沿途油站数N(N可以为零),油站i离出发点的距离Di、每升汽油价格Pi(i=1,2,…,N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。

输入输出格式

输入格式:

第一行,D1CD2PN

接下来有N行。

i+1行,两个数字,油站i离出发点的距离Di和每升汽油价格Pi。

输出格式:

所需最小费用,计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。

题目解析

看好多人用队列做的,然而并不想用

可以这样想,每次遇到加油站就把油箱里的“贵油”卖掉,再把油箱加满地沟油。得出的结果是一样的。

为了方便判断油的价格,rk[x]表示第x个油站的价格排名,bag[x]表示排名为x的油在油箱里有多少,注意细节模拟就可以了

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

const int MAXN = 10;

struct Station {
    int id;
    double price;
    friend bool operator < (Station x,Station y) {
        return x.price < y.price;
    }
} s[MAXN];

struct Oil {
    double sum;
    double price;
    double rk;
};

int n;
double cub,ech,ans;//分别是油箱容量,每升油跑多远,共多少钱
double p[MAXN],dis[MAXN],bag[MAXN];//价格 离起点的距离 油箱
int rk[MAXN];

int main() {
    double tmp;
    scanf("%lf%lf%lf%lf%d",&tmp,&cub,&ech,&p[1],&n);
    dis[n+2] = tmp;
    s[1].id = 1;
    s[1].price = p[1];
    n++;
    for(int i = 2;i <= n;i++) {
        scanf("%lf%lf",&dis[i],&p[i]);
        s[i].price = p[i];
        s[i].id = i;
        p[i] = s[i].price;
        if(dis[i]-dis[i-1] > cub*ech) {
            printf("No Solution
");
            return 0;
        }
    }
    sort(s+1,s+1+n);
    for(int i = 1;i <= n;i++) {
        rk[s[i].id] = i;
    }
//    for(int i = 1;i <= n;i++) {
//        cout<<i<<" "<<p[i]<<" "<<dis[i]<<" "<<rk[i]<<endl;
//    }
    for(int i = 1;i <= n+1;i++) {
        double tot = 0;
        double need = (dis[i]-dis[i-1]) / ech;
        for(int j = 1;j <= n;j++) {
            if(need >= bag[j]) need -= bag[j],bag[j] = 0;
            else if(need) {
                bag[j] -= need;need=0;
                break;
            }
        }
        if(i == n+1) break;
        for(int j = 1;j <= n;j++) {
            if(!bag[rk[j]]) continue;
            if(rk[i] < rk[j]) {
                ans -= bag[rk[j]] * (p[j]-p[i]);
                bag[rk[i]] += bag[rk[j]];
                bag[rk[j]] = 0;
            }
            tot += bag[rk[j]];
        }
        bag[rk[i]] += cub - tot;
        ans += (cub-tot) * p[i];
//        for(int j = 1;j <= n;j++) printf("%.2lf ",bag[j]);
//        cout<<" with ans is: "<<ans<<endl;
    }
    for(int i = 1;i <= n;i++) ans -= bag[rk[i]] * p[i];
    printf("%.2lf
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/floatiy/p/9674890.html