参考:https://www.cnblogs.com/lilibuxiangtle/p/13427959.html
题目描述
Tired of boring WFH (work from home), Apollo decided to open a fast food restaurant, called Kabaleo Lite extbf{Kabaleo Lite}Kabaleo Lite.
The restaurant serves n kinds of food, numbered from 1 to n. The profit for the i-th kind of food is aia_iai. Profit may be negative because it uses expensive ingredients. On the first day, Apollo prepared bib_ibi dishes of the i-th kind of food.
The peculiarity of Apollo's restaurant is the procedure of ordering food. For each visitor Apollo himself chooses a set of dishes that this visitor will receive. When doing so, Apollo is guided by the following rules:
The restaurant serves n kinds of food, numbered from 1 to n. The profit for the i-th kind of food is aia_iai. Profit may be negative because it uses expensive ingredients. On the first day, Apollo prepared bib_ibi dishes of the i-th kind of food.
The peculiarity of Apollo's restaurant is the procedure of ordering food. For each visitor Apollo himself chooses a set of dishes that this visitor will receive. When doing so, Apollo is guided by the following rules:
- every visitor should receive at least one dish.
- each visitor should receive continuous kinds of food started from the first food. And the visitor will receive exactly 1 dish for each kind of food. For example, a visitor may receive 1 dish of the 1st kind of food, 1 dish of the 2nd kind of food, 1 dish of the 3rd kind of food.
输入描述:
The first line of the input gives the number of test case, Tmathbf{T}T (1≤T≤101 leq mathbf{T} leq 101≤T≤10). Tmathbf{T}T test cases follow.
Each test case begins with a line containing one integers n (1≤n≤1051 le n le 10^51≤n≤105), representing the number of different kinds of food.
The second line contains n space-separated numbers aia_iai (−109≤ai≤109-10^9 le a_i le 10^9−109≤ai≤109), where aia_iai denotes the profit of one dish of the i-th kind.
The third line contains n space-separated numbers bib_ibi (1≤bi≤1051 le b_i le 10^51≤bi≤105), where bib_ibi denotes the number of the i-th kind of dishes.
输出描述:
For each test case, output one line containing ‘‘Case #x: y z′′``Case #x: y z''‘‘Case #x: y z′′, where x is the test case number (starting from 1), y is the maximum number of visitors, and z is the maximum possible profits.
示例1
输入
2 3 2 -1 3 3 2 1 4 3 -2 3 -1 4 2 1 2
输出
Case #1: 3 8 Case #2: 4 13
说明
For test case 1, the maximum number of visitors is 3, one of a possible solution is:
The first visitor received food 1, the profit is 2.
The second visitor received food 1, the profit is 2.
The third visitor received food 1 + food 2 + food 3, the profit is 2 + (-1) + 3.
题解:
题目大意:
- 有n种菜,每种菜的数量为bi,每个菜的盈利为ai
- 每个顾客必须是从第1种菜开始吃,连续地吃,每种吃一个
- 保证顾客最多的情况下,盈利最大
题解:
- 最大顾客数量就是b1,然后求盈利的前缀和,从大到小取就好(可以使用优先队列protiry_queue)
- 结果会超出long long,可以使用__int128,或者把大数拆开存储(拆成俩个long long)
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 typedef __int128 ll; 5 const ll N = 1e5 + 5; 6 ll a[N],b[N]; 7 ll dp[N];//dp存储价钱的前缀和 8 ll n,t; 9 10 #define P pair<ll, pair<ll, ll>> //第一个存dp[i], 第二个存数量, 第三个存菜的下标(第几道菜) 11 priority_queue <P> que; 12 13 inline int read(){ 14 int x=0,f=1; 15 char ch=getchar(); 16 while(ch<'0'||ch>'9'){ 17 if(ch=='-') 18 f=-1; 19 ch=getchar(); 20 } 21 while(ch>='0'&&ch<='9'){ 22 x=x*10+ch-'0'; 23 ch=getchar(); 24 } 25 return x*f; 26 } 27 28 inline void print(__int128 x){ 29 if(x<0){ 30 putchar('-'); 31 x=-x; 32 } 33 if(x>9) 34 print(x/10); 35 putchar(x%10+'0'); 36 } 37 38 ll solve() { 39 ll res = 0; 40 ll pos_now = n, now_food_num = 0; 41 42 while (!que.empty()) { 43 ll max_price = que.top().first; //最大利润 44 ll food_num = que.top().second.first; //菜品数量 45 ll pos = que.top().second.second; //菜品名 46 que.pop(); 47 if (pos_now <= pos || food_num <= now_food_num) { //当该菜品位置位于pos_now之后则不可上菜 48 continue; 49 } 50 51 res += (food_num - now_food_num) * max_price; //(需要减去上次用的菜品,因为其数量的价值上一次已经算过了) 52 now_food_num = food_num; //更新上一次用去的菜品数量 53 pos_now = pos; //更新菜品位置 54 } 55 return res; 56 } 57 int main() { 58 /* ios::sync_with_stdio(false); 59 cin.tie(0); cin.tie(0); */ 60 t = read(); 61 for(ll i = 1; i <= t; i++) { 62 n = read(); 63 for(ll j = 0; j < n; j++) { 64 a[j] = read(); 65 if (!j) dp[j] = a[j]; //dp存储价钱的前缀和 66 else dp[j] = dp[j-1] + a[j]; 67 } 68 69 for(ll j = 0; j < n; j++) { 70 b[j] = read(); 71 } 72 73 ll bb = b[0]; 74 for (ll j = 0; j < n; j++) { 75 bb = min(bb, b[j]); //因为当前面的菜没了的时候,后面的菜也相当于没有,所以一直更新前方菜品的最小值 76 que.push({dp[j], {bb, j}}); 77 } 78 79 ll ans = solve(); 80 cout << "Case #"; 81 print(i); 82 cout << ": "; 83 print(b[0]); 84 cout << " "; 85 print(ans); 86 puts(""); 87 } 88 /* clock_t end = clock(); 89 cout << end - start << " "; */ 90 return 0; 91 } 92 /* 93 2 94 6 95 1 1 1 1 1 1 96 8 3 2 1 9 3 97 6 98 2 -1 -3 4 5 -5 99 10 9 8 7 6 5 100 */