CF1185C2 Exam in BerSU (hard version)
题目描述:
Polygraph Poligrafovich 要去测试n位学生。学生们按照1到n的顺序依次测试。第i个考生随机抽取一题。学生可选做与不做,做则得到分数,不做则不及格。
所有学生总共考试时间是M,求对于第i个学生通过考试时,计算出前面最少的不及格的学生的人数。
输入:
n,M(1<=n,M<=100)
下面n个数表示第i个同学需要花费的时间ti
输出:
第i个学生通过考试时,计算出前面最少的不及格的学生的人数。
题解:
思路很简单,用一个大根堆heap储存前i个最大能通过的学生数中每个人的时间t,然后用sum在储存heap中所有元素的和。
在每次查询新的学生x时,如果time[x]+sum<=M则在heap中存入time[x],同时更新sum,输出结果即为i-heap.size()。
而如果time[x]+sum>M,分两种情况:
①time[x]<=heap.top(),则删除堆顶,同时将time[x]存入heap,同时更新sum,输出也为i-heap.size()。
②如果time[x]>heap.top(),由于当前学生x必须通过,故我们只需将heap的堆顶不断弹出,同时弹出时维护sum-=heap.top(),直至sum+time[x]<=M,输出i-heap.size()。(此处的heap和sum,后面依然要用到,所以我们可以用新的一组heap_t和sum_t储存后再操作)
代码:
#include <bits/stdc++.h> using namespace std; const int N = 2e5 + 10; int n, m; int a[N]; int sum = 0; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) cin >> a[i]; priority_queue<int>heap; for (int i = 1; i <= n; i++) { if (sum + a[i] <= m) { heap.push(a[i]); sum += a[i]; } else { int t = heap.top(); if (a[i] < t) {//删除堆顶小于t的所有元素 heap.pop(); heap.push(a[i]); sum = sum - t + a[i]; } else { priority_queue<int>heap_t = heap; int t = heap_t.top(); int sum_t = sum; while (a[i] + sum_t > m) {//弹出堆顶并维护 sum_t -= t; heap_t.pop(); t = heap_t.top(); } cout << i - heap_t.size() - 1 << ; continue; } } cout << i - heap.size() << ; } return 0; }
下一篇:
单例模式——设计模式个人学习