• 【stl 模拟】 内存分配


    传送门

    题意

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

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

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

    • 运行时间为(p)

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

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

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

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

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

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

    数据范围

    输入文件数(leq 10^{5})
    (1leq t,m,pleq 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;
    }
    
  • 相关阅读:
    mobx源码解读1
    表单元素之图形系
    koa2+koa-views示例
    avalon2的后端渲染实践
    向一个数组中插入元素
    一步步编写avalon组件02:分页组件
    avalon2学习教程15指令总结
    avalon2学习教程14动画使用
    WPF动态加载Menu菜单
    WPF自定义控件与样式 ---- 系列文章
  • 原文地址:https://www.cnblogs.com/hhyx/p/13740710.html
Copyright © 2020-2023  润新知