【stl 模拟】 内存分配

传送门

题意

内存的每个地址用一个固定的整数表示,从\(0\)开始排列,程序运行过程中每个进程需要占一定内存

  • 对于每个进程有一个申请时间\(t\)

  • 需要连续的内存单元数为\(m\)

  • 运行时间为\(p\)

  • 在运行时间\(p\)内,这\(m\)个内存就不能再被其他进程使用,

在某一时刻\(t\),一个进程申请\(m\)单元的地址,运行时间为\(p\)

  • 如果内存中存在长度为\(m\)的地址,则将这个分配

  • 存在多个满足的地址时优先分配首地址最小的,如果不存在就加入到等待队列中

  • 队列的进程满足时,会优先分配给队列中的,而不是当前时刻新到来的进程

求所有进程运行完毕的时间、等待队列一共被放入的进程个数

数据范围

输入文件数\(\leq 10^{5}\)
\(1\leq t,m,p\leq 10^{9}\)

题解

维护当前的状态:

  • 等待队列:(内存长度, 占用时间)

  • 内存使用情况:(起始下标,长度)

    • 线性扫描、删除、插入:\(set\)
  • 小根堆:(释放时间\(key\),起始下标)

新来一个请求:\((T,M,P)\)

  • 释放掉所有: 释放时间 \(\leq T\) 的内存,每次释放之后,都要判断等待队列的队头是否可以满足

  • 判断\((T,M,P)\)是否可以满足,如果不可以,则插入等待队列

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define fi first
#define se second
#define close ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

const int N=3e4+10;

typedef pair<int,int> pii;

int n;
int t,m,p;
queue<pii>w; //(内存长度,占用时间)
set<pii>mem; //(内存的起始下标,内存的长度) 
priority_queue<pii,vector<pii>,greater<pii>>prog; //(释放时间,起始下标)
int cnt,times;

bool push(int t,int m,int p)
{
    for(auto it = mem.begin(); it != mem.end(); it++)
    {
        auto jt = it; // set中的迭代器索引不能用.   用->
        jt++; // 当前内存片段的下一个片段,内存片段按照起始下标有序
        if(jt != mem.end())
            if(m <= jt->fi -(it->fi + it->se -1)-1)
            {
                int st = it->fi+it->se;

                mem.insert({st,m});
                prog.push({t+p,st});
                return true;
            }
    }
    return false;
}
void finish(int t)
{
    while(prog.size() && prog.top().fi <= t)
    {
        int ed = prog.top().fi;
        while(prog.size() && prog.top().fi == ed)
        {
            auto top=prog.top();
            prog.pop();
            auto it = mem.lower_bound({top.se,0}); //按照第一关键字进行查找
            mem.erase(it);
        }   
        times = ed;
        while(w.size())
        {
            auto h = w.front();
            if(push(ed,h.fi,h.se))
                w.pop();
            else break;
        }
    }
}
int main()
{
    cin>>n;
    mem.insert({-1,1});
    mem.insert({n,1});

    while(cin>>t>>m>>p,t||m||p)
    {
        finish(t);
        if(!push(t,m,p))
        {
            w.push({m,p});
            cnt++;
        }
    }
    finish(2e9);
    cout<<times<<endl<<cnt<<endl;
}
posted @ 2020-09-27 17:25  Hyx'  阅读(141)  评论(0编辑  收藏  举报