题意:种菜,每种菜利润为,数量为,问在尽可能服务多的客人的情况下,可以获得的最大利润是多少(可以为负数)。注意:除了吃第一种菜,吃第种菜前必须先吃第种菜。总共有组数据。
数据范围:

题解:
最多客人数即

第一种:整体考虑。
由于第一种菜必选,故从第二种菜开始考虑每次贪心地选可以吃到的总利润最大的菜,且的前置所有菜都没有被其他先来的客人吃完。则吃完后可以区间修改都减

第二种:拆分考虑。
考虑到第种菜的利润是否大于前面吃到的最大利润,如果大于,则把这个菜全部吃掉(最多吃盘),否则继续往后考虑直到利润大于前面吃到的最大利润。

拆分考虑的代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

template<typename T>
inline T Read(){
    T s = 0, f = 1; char ch = getchar();
    while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
    while(isdigit(ch)) {s = (s << 3) + (s << 1) + ch - '0'; ch = getchar();}
    return s * f;
}

inline void print(__int128 x){
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9) print(x / 10);
    putchar(x % 10 + '0');
}

#define read() Read<int>()
#define readl() Read<ll>()

const int N = 1e5 + 10;
const int M = N << 1;
ll a[N], b[N];
int n;

inline void prints(__int128 x){
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9) prints(x / 10);
    putchar(x % 10 + '0');
}

void solve(int num) {
    n = read();
    for(int i = 1; i <= n; i++) a[i] = readl(), a[i] += a[i - 1];
    for(int i = 1; i <= n; i++) b[i] = readl();
    for(int i = 2; i <= n; i++) b[i] = min(b[i - 1], b[i]);

    __int128 ans = (__int128)a[1] * b[1];
    int l = 1, r = 2;

    while(r <= n) {
        while(r <= n && a[r] <= a[l]) ++r;
        if(r == n + 1) break;
        ans += (__int128)(b[r]) * (a[r] - a[l]);
        l = r;
    }

    printf("Case #%d: %lld ", num, b[1]);
    prints(ans);
    puts("");

}

int main()
{
    int T = 1;
    T = read();
    for(int i = 1; i <= T; ++i) {   
        solve(i);
    }
}