bzoj 1029 贪心

首先对于结束时间排序,然后贪心就可以了,建立一个大根堆

维护一个当前结束时间,每次扫描到一个房屋,如果

当前结束时间+time[i]<=finishi[i]那么就更新结束时间,然后累加答案

否则比较堆顶元素时间和当前用时,当前用时小的话就相当于不做堆顶那个

任务,删除堆顶,加入当前时间。

/**************************************************************
    Problem: 1029
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time:808 ms
    Memory:1984 kb
****************************************************************/
 
//By BLADEVIL
var
    n                       :longint;
    time, fin               :array[0..150010] of longint;
    heap                    :array[0..150010] of longint;
    tot                     :longint;
     
procedure swap(var a,b:longint);
var
    c                       :longint;
begin
    c:=a; a:=b; b:=c;
end;
     
procedure qs(low,high:longint);
var
    i, j, x                 :longint;
begin
    i:=low; j:=high; x:=fin[(i+j) div 2];
    while i<j do
    begin
        while fin[i]<x do inc(i);
        while fin[j]>x do dec(j);
        if i<=j then
        begin
            swap(time[i],time[j]); 
            swap(fin[i],fin[j]);
            inc(i); dec(j);
        end;
    end;
    if i<high then qs(i,high);
    if j>low then qs(low,j);
end;
     
procedure init;
var
    i                       :longint;
begin
    read(n);
    for i:=1 to n do read(time[i],fin[i]);
    qs(1,n);
end;
 
procedure up(x:longint);
begin
    while (x>1) and (heap[x]>heap[x div 2]) do
    begin
        swap(heap[x],heap[x div 2]);
        x:=x div 2;
    end;
end;
 
procedure down(x:longint);
var
    k                       :longint;
begin
    while true do
    begin
        k:=x;
        if (x*2<=tot) and (heap[x*2]>heap[k]) then k:=x*2;
        if (x*2+1<=tot) and (heap[x*2+1]>heap[k]) then k:=x*2+1;
        if k=x then break;
        swap(heap[k],heap[x]);
        x:=k;
    end;
end;    
 
procedure insert(x:longint);
begin
    inc(tot);
    heap[tot]:=x;
    up(tot);
end;
 
procedure delete(x:longint);
begin
    heap[1]:=heap[tot];
    dec(tot);
    down(1);
end;
 
procedure main;
var
    i                       :longint;
    now                     :longint;
    ans                     :longint;
     
begin
    ans:=0;
    now:=0;
    for i:=1 to n do
    begin
        if now+time[i]<=fin[i] then
        begin
            now:=now+time[i];
            inc(ans);
            insert(time[i]);
        end else
        begin
            if time[i]<heap[1] then
            begin
                now:=now+time[i]-heap[1];
                delete(1);
                insert(time[i]);
            end;
        end;
    end;
    writeln(ans);
end;
 
begin
    init;
    main;
end.
原文地址:https://www.cnblogs.com/BLADEVIL/p/3463998.html