• 2020牛客暑期多校训练营(第八场) K


    K.Kabaleo Lite

    题目链接

    题意:

    有N个菜, 第 i 道菜有 盈利值 a[i] 和 数量 b[i]  , 每次给一位客人上菜 需要从第一道菜开始上,上完第一道菜才能上第二道菜 , 上完第二道菜才能上第三道菜 ...  以此类推

    问 最多能给几个客人上菜 , 在客人最大化的情况下 ,最大盈利是多少(可能为负)

    想法:

    ① 最多可以给b[1]个客人上菜 , 因为每个客人都一定要上第一道菜

    ② 假如 第 5 道菜数量为 1 , 第 6 道菜数量为 100 , 那么第 6 道菜的数量可以看做 1 ,因为 第 5 道菜只能上一次 , 而第 6 道菜只能在第 5 道上过了 才能上。

    ③ 计算一个 a[ i ] 前缀和 pre[ i ]  ,  含义是:总共上 [1  ~ i ]道菜 的利润

    ④ 只要从后往前 , 每次找到 [1 ~ i ] 中利润最高的 pre[ i ] ,然后看数量还够不够 , 如果够 , 就全取掉 , 如果不够 , 同理继续往前找。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6 + 10;
    #define ll long long
    #define int long long
    template <typename T>
    void read(T &res) {
        bool flag = false;
        char ch;
        while (!isdigit(ch = getchar())) (ch == '-') && (flag = true);
        for (res = ch - 48; isdigit(ch = getchar()); res = (res << 1) + (res << 3) + ch - 48)
            ;
        flag && (res = -res);
    }
    template <typename T>
    void Out(T x) {
        if (x < 0)
            putchar('-'), x = -x;
        if (x > 9)
            Out(x / 10);
        putchar(x % 10 + '0');
    }
    
    int a[maxn] , b[maxn];
    __int128 maxx[maxn] ,  pre[maxn];
    signed main() {
        //ios;
        //cin.tie(0);
        int t;
        read(t);
        int num = 1;
        while(t --){
           int n;
           read(n);
           for(int i = 1 ; i <= n ; i ++) read(a[i]) , pre[i] = pre[i - 1] + a[i];
           for(int i = 1 ; i <= n ; i ++) read(b[i]);
           for(int i = 2 ; i <= n ; i ++) b[i] = min(b[i] , b[i - 1]);
           int pos = 1;
           maxx[1] = pos;
           for(int i = 2 ; i <= n ; i ++){
                if(pre[i] > pre[pos]){
                    maxx[i] = i , pos = i;
                }
                else maxx[i] = maxx[i - 1];
           }
           __int128 ans = 0 , cnt = 0;
           for(__int128 i = n ; i >= 1 ; i --){
                __int128 now = maxx[i];
                if(cnt >= b[now])continue;
                ans += (b[now] - cnt) * pre[now];
                cnt += (b[now] - cnt);
    
           }
           cout << "Case #" << num ++ << ": " << b[1] << ' ';
           Out(ans);
           cout << '
    ';
        }
        return 0;
    }
    View Code
  • 相关阅读:
    JavaScript笔记三两个
    形式参数分别是基本类型和引用类型的调用
    if (strAreaCode.Find("体检")>=0)
    C++编写DLL文件
    error LNK2001: unresolved external symbol __imp__closesocket@4
    accept函数
    socket编程
    MFC控件使用大全
    DLL导出函数
    LINK : fatal error LNK1104: cannot open file的解决方法
  • 原文地址:https://www.cnblogs.com/GoodVv/p/13437260.html
Copyright © 2020-2023  润新知