//#include <bits/stdc++.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <queue>
#define x first
#define int long long
#define y second
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<char,int> PCI;
typedef pair<LL,LL> PLL;
//typedef __int128 i128;
typedef unsigned long long ULL;
const int N=1e5+10,INF = 1e9 ,mod = 1e9 + 7 ;
const double eps = 1e-7;
int n;
queue<PII> wait;//等待队列:(内存长度, 占用时间):queue
set<PII> run;
//内存使用情况:(起始下标,长度)
//线性扫描、删除、插入:set
priority_queue<PII,vector<PII>,greater<PII>> endts;//小顶堆
//小根堆:(释放时间key,起始下标),priority_queue
int tm,cnt;
bool give(int t,int m,int p)// 判断这个任务能否被执行
{
for(auto it =run.begin();it != run.end();it ++ )
{
auto j = it;j ++;
if(j != run.end())
{
if(m <= j->x - (it->x + it->y -1) - 1)
//j->x 下一段连续任务的开始的左边界, (it->x + it->y -1) 上一个任务结束时候的右边界 ,-1 :不包括下一个连续任务的左端点
{
int start =it->x + it->y;// 直接将当前任务接在前一个任务的后面
run.insert({start,m});//内存上的开始端点,占用的长度
endts.push({t + p, start});// 释放的时间,占用内存的起始下标
return 1;
}
}
}
return 0;
}
void finish(int t) // 执行完t时刻前的 所有任务
{
while(endts.size() && endts.top().x <=t ) // 当结束小顶堆中有数,且结束任务的时刻小于 当前时刻
{
int f =endts.top().x;
while(endts.size() && endts.top().x == f ) // 将同一时刻结束的任务删除
{
auto top = endts.top(); endts.pop();
auto it = run.lower_bound({top.y,0});// 找到当前任务 在内存中的位置
run.erase(it);
}
tm = f;// 总的时刻
while(wait.size())
{
auto front= wait.front();
if(give(f,front.x,front.y ))
// 查看当前任务的结束时刻下,能不能将等待队列中的任务加入到内存中
{
wait.pop();
}
else break;
}
}
}
void solve()
{
cin >> n;
int t,m,p;
run.insert({-1,1}),run.insert({n,1});
// 读入开始时间,占用内存,运行时间
while(cin >> t >> m >> p , t || m|| p)
{
finish(t);// 完成当前时刻前的所有任务
if(!give(t,m,p))//如果当前任务不能被 加入到内存中的话
{
wait.push({m,p}); //放入等待队列
cnt ++ ;
}
}
finish(2e9);// 完成剩余的 任务
cout << tm << endl << cnt << endl;
}
signed main()
{
// freopen("1.txt","r",stdin);
ios
LL T=1;
// cin>>T;
while(T -- )
{
solve();
}
return 0;
}
内存分配(二叉堆)
最新推荐文章于 2024-11-02 16:10:25 发布