Cod sursa(job #19302)

Utilizator bigsarpeadrian bigsarpe Data 19 februarie 2007 10:14:40
Problema Ghiozdan Scor 64
Compilator fpc Status done
Runda Arhiva de probleme Marime 2.92 kb
const maxn=75000;maxbuc=200;oo=maxlongint div 4;
var t:text;
   count:array[0..maxbuc+30]of longint;
   j,old,pas,modu,tmp,lo,hi,i,n,g,cit,rest:longint;
   Q,V,Scade:Array[0..maxn]of longint;
   Best:array[0..10,0..maxn]of longint;
   Rec:Array[0..10,0..maxn]of word;
   Save:array[0..20,0..maxn]of longint;
   lgsave:longint;
   Procedure dinamica(tip,dist:longint;var A,B:array of longint);
   var i,j:longint;
   begin
      hi:=0;
      for i:=G downto 0 do
      begin scade[i]:=hi;V[i]:=A[i]+hi;if i mod tip=0 then inc(hi);end;
      for rest:=0 to tip-1 do
      begin
         lo:=1;hi:=0;i:=rest;
         while i<=G do
         begin
            if i>=tip*dist then j:=dist else j:=i div tip;
            while (lo<=hi)and(V[Q[hi]]>v[i]) do dec(hi);inc(hi);Q[hi]:=i;
            while Scade[Q[lo]]>Scade[i]+j do inc(lo);
            tmp:=V[Q[lo]]-Scade[i];if tmp<A[i] then B[i]:=tmp else B[i]:=A[i];
            inc(i,tip);
         end;
      end;
   end;
   Procedure Redinamica(G,tip,dist:longint;var A,B:array of longint;var R:array of word);
   var i,j:longint;
   begin
      hi:=0;
      for i:=G downto 0 do
      begin scade[i]:=hi;V[i]:=A[i]+hi;if i mod tip=0 then inc(hi);end;
      for rest:=0 to tip-1 do
      begin
         lo:=1;hi:=0;i:=rest;
         while i<=G do
         begin
            if i>=tip*dist then j:=dist else j:=i div tip;
            while (lo<=hi)and(V[Q[hi]]>v[i]) do dec(hi);inc(hi);Q[hi]:=i;
            while Scade[Q[lo]]>Scade[i]+j do inc(lo);
            tmp:=V[Q[lo]]-Scade[i];if tmp<A[i] then
            begin R[i]:=Scade[Q[lo]]-Scade[i];B[i]:=tmp;end else B[i]:=A[i];
            inc(i,tip);
         end;
      end;
   end;
begin
   writeln((sizeof(q)*3+sizeof(best)+sizeof(rec)+sizeof(save))div 1024);
   assign(t,'ghiozdan.in');reset(T);readln(t,n,G);
   for i:=1 to N do begin readln(t,cit);inc(count[cit]);end;close(T);
   for i:=1 to G do Best[0,i]:=oo;i:=1;Save[0]:=Best[0];
   while i<=maxbuc do
   begin
      modu:=0;
      for pas:=0 to 8 do
      begin
         Dinamica(i,count[i],best[modu],Best[modu+1]);
         inc(modu);inc(i);
      end;
      Dinamica(i,count[i],best[modu],Best[0]);
      inc(i);inc(lgsave);Save[lgsave]:=Best[0];
   end;
   for i:=G downto 0 do if Save[lgsave,i]<>oo then break;
   assign(t,'ghiozdan.out');rewrite(T);writeln(t,i,' ',Save[lgsave,i]);
   old:=i;
   lgsave:=1;
   for pas:=lgsave-1 downto 0 do
   begin
      Best[0]:=Save[pas];modu:=0;fillchar(Rec,sizeof(rec),0);
      for i:=pas*10+1 to  (pas+1)*10 do
      begin
         Redinamica(old,i,count[i],Best[modu],Best[modu+1],Rec[modu+1]);
         inc(modu);
      end;
      while modu>0 do
      begin
         tmp:=Rec[modu,old];for j:=1 to tmp do writeln(t,i);
         old:=old-i*tmp;dec(modu);dec(i);
      end;
   end;
   close(t);
end.