题意: 有种菜,每种菜利润为
,数量为
,问在尽可能服务多的客人的情况下,可以获得的最大利润是多少(可以为负数)。注意:除了吃第一种菜,吃第
种菜前必须先吃第
种菜
。总共有
组数据。
数据范围:
题解:
最多客人数即。
第一种:整体考虑。
由于第一种菜必选,故从第二种菜开始考虑每次贪心地选可以吃到的总利润最大的菜,且
的前置所有菜都没有被其他先来的客人吃完。则吃完后可以区间修改
都减
第二种:拆分考虑。
考虑到第种菜的利润是否大于前面吃到的最大利润,如果大于,则把
这个菜全部吃掉(最多吃
盘),否则继续往后考虑直到利润大于前面吃到的最大利润。
拆分考虑的代码:
#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); } }