1 条题解

  • 0
    @ 2025-4-14 18:45:30

    C++ :

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #define INF 10000000
    #define N 1000010
    using namespace std;
    double ci[N],pi[N];
    double dp[N];
    int main()
    {
        double l,c,m,s;
        int n;
        while(cin>>l>>c>>m>>pi[0]>>n)
        {
            for(int i=1;i<=n;i++)
            {
                scanf("%lf%lf",&ci[i],&pi[i]);
            }
            ci[0]=0,ci[n+1]=l,pi[n+1]=INF;
            s=c*m;
            for(int i=0;i<=n+1;i++)
                dp[i]=INF;
            dp[0]=0;
            int flag=0;
            for(int i=0;i<=n;i++)
            {
                for(int j=i+1;j<=n+1;j++)
                {
                    if(s>=ci[j]-ci[i])
                    {
                        dp[j]=min(dp[j],dp[i]+pi[i]*(ci[j]-ci[i])/m);
                    }
                    else
                    {
                        if(s>=ci[j]-ci[j-1])
                            dp[j]=min(dp[j],dp[i]+(pi[i]*s+pi[j-1]*(ci[j]-ci[i]-s))/m);
                        else
                        {
                            flag=1;
                            break;
                        }
                    }
                }
                if(flag==1)
                    break;
            }
            if(dp[n+1]==INF)
                cout<<"No Solution"<<endl;
            else
                printf("%.2lf\n",dp[n+1]);
        }
        return 0;
    }
    

    Pascal :

    var
     value,over,way,x:array[0..500]of real;
     l,c,dc,p0,ans:real;
     i,j,n:integer;
    begin
     readln(l,c,dc,p0,n);
     for i:=1 to n do
       readln(way[i],value[i]);
     for i:=0 to n do
       begin over[i]:=0;x[i]:=0;end;
     inc(n);way[n]:=l;value[n]:=0;
     i:=0;
     l:=c*dc;
     value[0]:=p0;way[0]:=0;over[0]:=0;
     repeat
       j:=i+1;
       if way[j]-way[i]>l then begin writeln('No Solution');halt end;
       while way[j]-way[i]<=l do
         begin
           if value[j]<value[i] then break;
           inc(j);
         end;
       if way[j]-way[i]<=l then
         if over[i]*dc>=way[j]-way[i] then
           over[j]:=over[i]-(way[j]-way[i])/dc
         else x[i]:=(way[j]-way[i])/dc-over[i]
       else
       begin
         x[i]:=c-over[i];
         j:=i+1;
         over[j]:=c-(way[j]-way[i])/dc;
       end;
       i:=j;
     until i=n;
     ans:=0;
     for i:=0 to n-1 do
       ans:=ans+x[i]*value[i];
     writeln(ans:0:2);
    end.
    

    Java :

    import java.util.*;
    
    public class Main {
    
        public static void main(String[] args) {
            Scanner sin = new Scanner(System.in);
            double totalDist = sin.nextDouble();
            double capacity = sin.nextDouble();
            double distPerGas = sin.nextDouble();
            double p0 = sin.nextDouble();
            int n = sin.nextInt();
            double[] dist = new double[n+2];
            double[] price = new double[n+1];
            dist[0] = 0.0;dist[n+1] = totalDist;
            price[0] = p0;
            for(int i=1;i<n+1;i++) {
                dist[i] = sin.nextDouble();
                price[i] = sin.nextDouble();
            }
            Deque<Node> queue = new LinkedList<>();
            double nowCapacity = 0.0;
            double cost = 0.0;
            for(int i=0;i<n+1;i++) {
                //装油
                if(queue.isEmpty()) {
                    queue.add(new Node(price[0], capacity));
                    nowCapacity = capacity;
                }else {
                    //如果油箱里有贵的油,退掉
                    while(!queue.isEmpty() && price[i] < queue.getLast().price) {
                        Node noNeedGas = queue.pollLast();
                        nowCapacity -= noNeedGas.cap;
                    }
                    //装油
                    queue.add(new Node(price[i], capacity-nowCapacity));
                    nowCapacity = capacity;
                }
                //烧油
                if(nowCapacity < (dist[i+1]-dist[i])/distPerGas) {
                    System.out.println("No Solution");
                    return;
                }else {
                    //烧最便宜的
                    double targetCapacity = (dist[i+1]-dist[i])/distPerGas;
                    while(targetCapacity > 0.0) {
                        Node firstGas = queue.getFirst();
                        if(firstGas.cap >= targetCapacity) {
                            firstGas.cap -= targetCapacity;
                            cost += targetCapacity * firstGas.price;
                            nowCapacity -= targetCapacity;
                            targetCapacity = 0.0;
                        }else {
                            cost += firstGas.cap * firstGas.price;
                            targetCapacity -= firstGas.cap;
                            nowCapacity -= firstGas.cap;
                            queue.poll();
                        }
                    }
                }
            }
            System.out.printf("%.2f%n", cost);
        }
    
    }
    class Node{
        double price;
        double cap;
        Node(double price, double cap){
            this.price = price;
            this.cap = cap;
        }
    }
    
    • 1

    信息

    ID
    3437
    时间
    1000ms
    内存
    125MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者