Cod sursa(job #18978)

Utilizator moga_florianFlorian MOGA moga_florian Data 18 februarie 2007 16:15:11
Problema Ghiozdan Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.72 kb
using namespace std;
#include<fstream>
#include<stdio.h>
#define nmax 20004
#define gmax 75005
#define cst 30

int vg[nmax];
int gok[2510];
int nmin[gmax],ant[gmax],sol[nmax],nsol;

int main()
{
FILE *fin=fopen("ghiozdan.in","r"),
     *fout=fopen("ghiozdan.out","w");
     
int n,g,j,i,k,nou,crt,aux;    
fscanf(fin,"%d%d",&n,&g);
for(i=1;i<=n;i++)
  fscanf(fin,"%d",&vg[i]);
  
for(i=1;i<=n;i++)
  {
  j=i;
  while(j/2&&vg[j/2]<vg[j])
      {
      aux=vg[j/2];
      vg[j/2]=vg[j];
      vg[j]=aux;
      
      j/=2;                           
      }               
  }
  
i=n;
while(i>1)
 {
 aux=vg[1];
 vg[1]=vg[i];
 vg[i]=aux;
 i--;
 
 j=1;
 while(1)
   {
   k=2*j;
   if(k>i) break;
   if(k+1<=i&&vg[k+1]>vg[k]) k++;
   if(vg[j]>=vg[k]) break;
   
   aux=vg[j];
   vg[j]=vg[k];
   vg[k]=aux;
   j=k;
   }         
 }
  
memset(gok,0,sizeof gok);
memset(nmin,0,sizeof nmin);
gok[0]=1;
int gata;

for(i=n;i;i--)
   {//adaug vg[i]
    gata=0;
    for(j=2500;j>=0&&gata==0;j--)
       if(gok[j])
         for(k=cst-1;k>=0&&gata==0;k--)
            if((1<<k)&gok[j])
             {
             crt=j*cst+k;
             if(crt<=g&&crt+vg[i]<=g)
                {
                nou=crt+vg[i];   
                if(nmin[nou]==0)
                    {
                    nmin[nou]=nmin[crt]+1;
                    ant[nou]=crt;
                    gok[nou/cst]|=(1<<(nou%cst));
                    }
                else
                if(vg[i]==vg[i-1])
                   gata=1;
                }        
             }             
   }  
   
for(i=g;nmin[i]==0;i--);
fprintf(fout,"%d %d\n",i,nmin[i]);
nsol=0;
ant[0]=-1;
while(ant[i]>=0)
   {
   fprintf(fout,"%d\n",i-ant[i]);
   i=ant[i];             
   }
    
fclose(fin);
fclose(fout);
return 0;
}