内存分配(二叉堆)

155. 内存分配 - AcWing题库

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值