BZOJ1226/SDOI2009/学校食堂

Posted on By 二价氢

AC-Code(为了能用负数下标,所以用了Pascal):

var
    a,d,e,g,h,i,j,k,l,m,n,o,p,q,r,s,u,v,w,x,y,z,C,kk,ans:longint;
    flag:boolean;
    b,t:array[0..1005] of longint;
    f:array[0..1005,0..255,-10..10] of longint;
procedure work;
begin
    fillchar(b,sizeof(b),0);
    fillchar(t,sizeof(t),0);
    ans:=maxlongint;
    readln(n);
    for i:=1 to n do
        readln(t[i],b[i]);
    filldword(f,sizeof(f)>>2,maxlongint);
    for i:=1 to 8 do
        f[1,1<<(i-1),i-1]:=0;
    for i:=1 to n do begin
        for j:=0 to 1<<8-1 do begin
            for k:=-8 to 8 do begin
                if (f[i,j,k]<>maxlongint) then begin
                    flag:=true;
                    e:=j;
                    q:=0;
                    while (e>0) do begin
                        if (e-e>>1<<1=0) then begin
                            if (e>(1<<(b[i+q]+1)-1)) then begin
                                flag:=false;
                                break;
                            end;
                        end;
                        inc(q);
                        e:=e>>1;
                    end;
                    if (not flag) then continue;
                    for c:=0 to b[i] do begin
                        if ((j>>c)-(j>>c)>>1<<1=0) then begin
                            e:=i+c;
                            q:=i+k;
                            if (q>=1) and(q<=n) and(e>=1) and(e<=n) then begin
                                s:=f[i,j,k]+(t[q] or t[e])-(t[q] and t[e]);
                                if (s<f[i,j or (1<<c),c]) then
                                    f[i,j or (1<<c),c]:=s;
                            end;
                        end;
                    end;
                    if (j-j>>1<<1=1)then
                        if (f[i,j,k]<f[i+1,j>>1,k-1])then
                            f[i+1,j>>1,k-1]:=f[i,j,k];
                end;
            end;
        end;
    end;
    for i:=-8 to 8 do
        if (f[n,1,i]<ans)then
            ans:=f[n,1,i];
    writeln(ans);
end;
begin
    readln(kk);
    while (kk>0) do begin
        dec(kk);
        work;
    end;
end.