【BZOJ】【P3117】【NOI1999】【内存分配】【题解】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3117

认认真真模拟就行,时间用优先队列,内存用链表,注意各种细节。

PS:代码好丑啊……

Code:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cctype>
#include<queue>
#include<set>
#include<vector>
#include<list>
using namespace std;
const int maxn=1e4+10;
int getint(){
	int res=0;
	char ch,ok=0;
	while(1){
		ch=getchar();
		if(isdigit(ch)){
			res*=10;res+=ch-'0';ok=1;
		}else if(ok)break;		
	}return res;
}
struct task{
	int t,m,p,f,ind;
	task(int _t=0,int _m=0,int _p=0,int _f=0,int _ind=0){
		t=_t,m=_m,p=_p,f=_f,ind=_ind;
	}
};
task tasks[maxn<<1];
int n,ans1,ans2,tot;
struct cmp{
	bool operator()(int a,int b){return tasks[a].t>tasks[b].t||(tasks[a].t==tasks[b].t&&tasks[a].f>tasks[b].f);}
};
priority_queue<int,vector<int>,cmp>que;
queue<int>q;
struct block{
	int l,r,ind,used;
	block(int _l=0,int _r=0,int _ind=0,int _used=0){
		l=_l,r=_r,ind=_ind,used=_used;
	}
};
list<block>List;
void deb(){
	for(list<block>::iterator it=List.begin();it!=List.end();it++)
	printf("l:%d r:%d ind:%d\t",it->l,it->r,it->ind);cout<<endl;
}
bool insert(int x){
	for(list<block>::iterator it=List.begin();it!=List.end();it++){
		if(!it->used&&(it->r-it->l+1>=tasks[x].m)){
			list<block>::iterator i=List.insert(++it,block(it->l,it->l+tasks[x].m-1,x,1));
			it=--i;i++;
			if(it->l+tasks[x].m-1<it->r)
			List.insert(++i,block(it->l+tasks[x].m,it->r,0,0));
			List.erase(it);
			return true;
		}
	}
	return false;
}
void erase(int x){
	if(List.size()==1){List.begin()->ind=0,List.begin()->used=0;return;}
	for(list<block>::iterator it=List.begin();it!=List.end();it++){
		if(it->ind==x){
			if(it==List.begin()){
				list<block>::iterator nxt=it;nxt++;
				if(!nxt->used){
					List.insert(++nxt,block(1,nxt->r,0,0));
					List.pop_front();List.pop_front();
				}else it->ind=0,it->used=0;
			}else
			if(it==--List.end()){
				list<block>::iterator pre=it;pre--;
				if(!pre->used){
					List.insert(pre,block(pre->l,n,0,0));
					List.pop_back();List.pop_back();
				}else it->ind=0,it->used=0;
			}else{
				list<block>::iterator pre=it;pre--;
				list<block>::iterator nxt=it;nxt++;
				if(!pre->used&&!nxt->used){
					list<block>::iterator i=List.insert(pre,block(pre->l,nxt->r,0,0));
					i++;
					i=List.erase(i);i=List.erase(i);i=List.erase(i);
				}else
				if(!pre->used){
					list<block>::iterator i=List.insert(pre,block(pre->l,it->r,0,0));
					i++;
					i=List.erase(i);i=List.erase(i);
				}else
				if(!nxt->used){
//					cout<<it->l<<" "<<nxt->r<<endl;
					list<block>::iterator i=List.insert(it,block(it->l,nxt->r,0,0));					
					i++;
					i=List.erase(i);i=List.erase(i);					
				}else it->ind=0,it->used=0;
			}break;
		}
	}
}
int main(){
	n=getint();List.push_back(block(1,n,0,0));
	while(++tot){
		tasks[tot].t=getint(),tasks[tot].m=getint(),tasks[tot].p=getint();
		if(tasks[tot].t==0&&tasks[tot].m==0){tot--;break;}
		tasks[tot].f=1;tasks[tot].ind=tot;
		que.push(tot);
	}	
	while(!que.empty()){
		int top=que.top(),tt=top;
		ans1=max(ans1,tasks[top].t);
//		cout<<tasks[top].t<<endl;
//		deb();
		if(tasks[top].f==1){
//			deb();	
que.pop();
			if(insert(top)){
				++tot;
				tasks[tot]=tasks[top];
				tasks[tot].t=tasks[top].t+tasks[tot].p;ans1=max(ans1,tasks[tot].t);
				tasks[tot].f=-1;
				que.push(tot);
			}else{
				q.push(top);
				ans2++;
			}		
//			deb();
		}else{
			bool jj=0;
//			deb();
			while(que.size()>1){
				top=que.top();que.pop();
				int tp=que.top();
				if(tasks[top].f==-1){
				erase(tasks[top].ind);}
				else{
					que.push(tp);
					break;
				}
				if(tasks[top].f==-1&&tasks[tp].f==-1&&tasks[tp].t==tasks[top].t){
//					que.pop();
				}else {
					jj=1;break;
				}
			}if(!que.empty()&&!jj){
				top=que.top();
				if(tasks[top].f==-1){
				erase(tasks[top].ind),que.pop();}
			}
			if(q.size())
			while(insert(q.front())){
				++tot;
				tasks[tot]=tasks[q.front()];
				tasks[tot].t=tasks[tt].t+tasks[tot].p;ans1=max(ans1,tasks[tot].t);
				tasks[tot].f=-1;
				que.push(tot);
				q.pop();if(q.empty())break;				
			}
		}
//		deb();
	}
	cout<<ans1<<endl;
	cout<<ans2<<endl;
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值