梦熊 11.17NOIP模拟赛题解

T1P11289 【MX-S6-T1】「KDOI-11」打印


原题链接

这道题是贪心+单调队列,主要就是考单调队列的。

来看看暴力45分做法。

使用一个优先队列存储每个节点信息,然后每次取队顶,对于每一次时间增加我们重新更新队列。

由于优先队列不支持直接修改,也没有迭代器,因此我们只能一个一个更新出队再进队,所以非常费时。

#include <bits/stdc++.h>
using namespace std;
#define maxn int(2e5)
#define _for(a,b,c) for(int i = a;i <= b;i+=c)
struct p{
   
	int nxt,id;
	bool operator < (const struct p &a) const{
   
		return nxt == a.nxt ? id > a.id : nxt > a.nxt;
	}
};
priority_queue<p> q;
struct wj{
   
	int s,t,id;
} w[maxn];
bool cmp(wj A,wj B){
   return A.t < B.t;}
int read(){
   
    int X=0,w=0; char c=0;
    while(c<'0'||c>'9') {
   w|=c=='-';c=getchar();}
    while(c>='0'&& c<='9') X=(X<<3)+(X<<1)+(c^48),c=getchar();
    return w? -X : X;
}
vector<int> ans[maxn+10];
int c1[maxn+10],c2[maxn+10];
signed main(){
   
	int n = read(),m = read();
	_for(1,n,1) w[i].s = read(),w[i].t = read(),w[i].id = i;
	sort(w+1,w+1+n,cmp);
	_for(1,m,1) q.push(p{
   0,i}); 
	_for(1,n,1){
   
		int tot = 0;
		while(!q.empty()){
   
			int tmp1 = q.top().nxt;
			tmp1 -= (w[i].t - w[i-1].t);
			if(tmp1 < 0) tmp1 = 0;
			int tmp2 = q.top().id;
			q.pop();
			c1[++tot] = tmp1,c2[tot] = tmp2;
		}
		for(int j = 1;j <= tot;j++){
   
			q.push((p){
   c1[j],c2[j]});
		}
		//printf("%d %d\n",q.top().nxt,q.top().id);
		ans[q.top().id].push_back(w[i].id);
		int tmp = q.top().nxt + w[i].s;
		int tmp2 = q.top().id;
		q.pop();
		q.push((p){
   tmp,tmp2}); 
	}
	_for(1,m,1){
   
		printf("%d ",ans[i].size());
		sort(ans[i].begin(),ans[i].end());
		for(int j = 0;j < ans[i].size();j++) printf("%d ",ans[i][j]);
		printf("\n");
	}
	return 0;
}

接下来想想正解:

首先按照下发命令的 t t t给它排序,接下来考虑一个一个的分配给打印机。

由于每次会选择等待时间最短的打印机,所以可以用两个优先队列来维护,一个优先队列 q q q用来维护当前需要等待的打印机要等多久以及其编号,另一个 n u m num num用来维护不用等待的打印机的编号。

每一次先把已经打印完的打印机出队,并让这些打印机的编号插入 n u m num num,接下来开始判断当前这个文件该用哪个打印机来打印,有以下两种情况:

  • n u m num n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值