cf536b——优先队列的运用
题目
题目:cf536 B题
题目大意:一个饭店有n种食物,每种食物有对应的价格和数量,然后有m个顾客,每个顾客需要$d_j$份第$t_j$种食物,如果该种食物数量不够,则选其它尽可能便宜的代替(出现同样价格的应选索引最小的);如果所有的食物都不够该顾客,该顾客会吃完这些食物,并且不花钱。假设只有当前一个顾客服务完下一个才会来。
思路
模拟,根据题目所说的去做即可。唯一的困难是得到最便宜的食物,这需要对食物进行排序,由于同时还要记录原来的索引,所以用pair存储,放在优先队列中。
时间复杂度:$\mathcal{O}(m + n \log n)$
代码
1 #include<cstdio> 2 #include<algorithm> 3 #include<queue> 4 using namespace std; 5 6 typedef long long LL; 7 typedef pair<int,int> PII; 8 9 const int maxn = 100000 + 10; 10 int n, m,r[maxn],c[maxn]; 11 priority_queue<PII, vector<PII>, greater<PII>>Q; //优先第一维比较,第一维相同则根据第二维 12 13 int main() 14 { 15 scanf("%d%d", &n, &m); 16 for (int i = 1; i <= n; i++) scanf("%d", &r[i]); 17 for (int i = 1; i <= n; i++) 18 { 19 scanf("%d", &c[i]); 20 Q.push(PII(c[i], i)); 21 } 22 for (int i = 1; i <= m; i++) 23 { 24 int t, d; 25 scanf("%d%d", &t, &d); 26 if (d <= r[t]) 27 { 28 r[t] -= d; 29 printf("%lld\n", 1LL * d * c[t]); 30 } 31 else 32 { 33 bool flag = false; 34 LL ans = 1LL * r[t] * c[t]; 35 d -= r[t]; 36 r[t] = 0; 37 while (!Q.empty()) 38 { 39 while (!Q.empty() && r[Q.top().second] == 0) Q.pop(); 40 if (Q.empty()) break; 41 PII now = Q.top(); 42 if (d <= r[now.second]) 43 { 44 r[now.second] -= d; 45 ans += 1LL * d * now.first; 46 flag = true; 47 printf("%lld\n", ans); 48 break; 49 } 50 else 51 { 52 ans += 1LL * r[now.second] * now.first; 53 d -= r[now.second]; 54 r[now.second] = 0; 55 Q.pop(); 56 } 57 } 58 if (!flag) printf("0\n"); 59 } 60 } 61 return 0; 62 }
个性签名:时间会解决一切