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;
}

​

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值