[hihocoder1198] Memory Allocating Algorithm

链接:https://hihocoder.com/problemset/problem/1198?sid=1370091

思路:

(1)直接模仿内存分配方式。定义Node(bg,ed,val),bg表示分配内存的开始index,ed表示结束下表(不含),val表示id;

(2)维护两个list,已分配used,空闲freed;

(3)不变性:保证freed空闲块是递增的,每次插入新的空闲节点时需要和原有空闲链表中能合并的合并;

(4)约束条件:由于不变性,每次插入新的空闲节点时,最多合并两次[a,b),[c,d),插入[b,c)时将合并为一个节点[a,d);

(5)分配:每次遍历空闲链表,寻找index最小的一块进行分配,若无,则从used中选择最早分配的内存块(used.front())。

时间复杂度为O(N*M),代码如下:

#include 
#include 
using namespace std;
struct Node{
    int bg,ed,val;
    Node(int _b,int _e,int _v):bg(_b),ed(_e),val(_v){}
};
list used,freed;
int n,m;

void insertNode(Node& no){
    auto p=freed.begin();
    while(p!=freed.end()){
        if(p->ed==no.bg){
            no.bg=p->bg;
            p=freed.erase(p);
        }else if(p->bg==no.ed){
            no.ed=p->ed;
            p=freed.erase(p);
        } else
            ++p;
    }
    auto pit=freed.begin();
    while(pit!=freed.end() && pit->bgbg+sz>p->ed)
            p++;
        if(p->bg+sz<=p->ed){
            used.emplace_back(Node(p->bg,p->bg+sz,i));
            succ=true;
            p->bg+=sz;
            if(p->bg==p->ed)
                p=freed.erase(p);
        }else{
            auto no=used.front();
            insertNode(no);
            used.pop_front();
        }
    }
}
int main() {
    scanf("%d%d",&n,&m);
    freed.emplace_back(Node(0,m,0));
    int sz;
    for(int i=1;i<=n;++i){
        scanf("%d",&sz);
        allocMem(sz,i);
    }
    for(auto it=used.begin();it!=used.end();++it){
        printf("%d %d\n",it->val,it->bg);
    }
    return 0;
}

 

你可能感兴趣的:(算法,hiho刷题日记)