• HDU5380——单调队列——Travel with candy


    http://acm.hdu.edu.cn/showproblem.php?pid=5380

    /*
    双端队列
    题意:加油问题,从起始到终点。,每走一步需要消耗1L油,中途可以买卖油,有一个最大油量,问你到达终点的最少花费是多少
    用一个双端队列维护
    
    
    */
    /************************************************
    * Author        :Powatr
    * Created Time  :2015-8-17 18:28:49
    * File Name     :HDU5380.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int MAXN = 2e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    
    int n, c;
    int buy[MAXN*2], sell[MAXN*2];
    int a[MAXN];
    struct P{
        int val, num;
    }q[MAXN];
    ll ans;
    int l, r;
    int cnt;
    void MAX(int x)
    {
        //把所有买的价格小于x的油都用x卖出
        int sum = 0;
        while(l <= r && x > q[l].val){
            sum += q[l].num;
            l++;
        }
        if(sum){
            q[--l].num = sum;
            q[l].val = x;
        }
    }
    
    void MIN(int x)
    {
        //把所有卖的价格大于x的油都用x买入
        while(l <= r && x < q[r].val){
            ans -= 1ll * q[r].val * q[r].num;
            cnt += q[r].num;
            r--;
        }
    }
    
    int DEL(int x)
    {
        //路上所要消耗的油
        while(x){
            int v = min(x, q[l].num);
            q[l].num -= v;
            x -= v;
            if(q[l].num == 0) l++;
        }
    }
    
    int main(){
        int T;
        scanf("%d", &T);
        while(T--){
            scanf("%d%d", &n, &c);
            for(int i = 1; i <= n; i++)
                scanf("%d", &a[i]);
            for(int i = 0; i <= n; i++)
                scanf("%d%d", &buy[i], &sell[i]);
            ans = 0;
             l = r = n;
            r--;
            for(int i = 0; i < n; i++){
                MAX(sell[i]);
                cnt = (i == 0 ? c : a[i] - a[i-1]);//所需要的油
                MIN(buy[i]);
                r++;
                q[r].val = buy[i];
                q[r].num = cnt;
                ans += 1ll * cnt * buy[i];//把油装满所需要的钱
                DEL(a[i+1] - a[i]);
            }
          MAX(sell[n]);
          for(int i = l; i <= r; i++)
              ans -= 1ll * q[i].val * q[i].num;
          printf("%I64d
    ", ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Spring Batch与ETL工具比较
    Spring Batch基本概念
    SpringBatch介绍
    2019第51周日
    用arthas的watch方法观察执行方法的输入输出
    三人行必有我师
    用arthas查看JVM已加载的类及方法信息
    线上问题排查利器Arthas
    换个视觉
    Java Servlet:服务器小程序
  • 原文地址:https://www.cnblogs.com/zero-begin/p/4737488.html
Copyright © 2020-2023  润新知