Cod sursa(job #18210)

Utilizator stef2nStefan Istrate stef2n Data 18 februarie 2007 10:41:46
Problema Ghiozdan Scor 62
Compilator cpp Status done
Runda preONI 2007, Runda 2, Clasele 11-12 Marime 1.99 kb
#include <stdio.h>
//#include <time.h>
//#include <stdlib.h>

#define infile "ghiozdan.in"
#define outfile "ghiozdan.out"
#define GMAX 75005
#define NMAX 20005

FILE *fin,*fout;
int n,g,w[NMAX];
int suma[GMAX],last[GMAX];
//clock_t start,end;
short int min[1705][1705],prec[1705][1705];

void citire()
  {
   int i;
   fin=fopen(infile,"r");
   fscanf(fin,"%d %d",&n,&g);
   for(i=0;i<n;i++)
      fscanf(fin,"%d",&w[i]);
   fclose(fin);
  }

void solve()
  {
   int i,j;
   for(i=1;i<=g;i++)
      suma[i]=-1;
   suma[0]=0;
   for(i=0;i<n;i++)
      for(j=g;j>=0;j--)
         if(suma[j]!=-1 && j+w[i]<=g)
           if(suma[j+w[i]]==-1)
             {
              suma[j+w[i]]=suma[j]+1;
//              last[j+w[i]]=i;
             }
           else
             if(suma[j+w[i]]>suma[j]+1)
               {
                suma[j+w[i]]=suma[j]+1;
//                last[j+w[i]]=i;
               }
  }

void solution()
  {
   while(g)
        {
         fprintf(fout,"%d\n",w[last[g]]);
         g-=w[last[g]];
        }
  }

void solution2()
  {
   while(g!=0 && n!=0)
        {
         if(min[n][g]==min[n-1][g])
           n--;
         else
           {
            fprintf(fout,"%d\n",w[prec[n][g]]);
            g-=w[prec[n][g]];
            n--;
           }
        }
  }

void rucsac()
  {
   int i,j;
   for(j=1;j<=g;j++)
      min[0][j]=-1;
   min[0][0]=0;
   for(i=1;i<=n;i++)
      for(j=0;j<=g;j++)
         {
          min[i][j]=min[i-1][j];
          prec[i][j]=prec[i-1][j-1];
          if(j-w[i-1]>=0 && min[i-1][j-w[i-1]]!=-1)
            if((min[i][j]>min[i-1][j-w[i-1]]+1) || min[i][j]==-1)
              {
               min[i][j]=min[i-1][j-w[i-1]]+1;
               prec[i][j]=i-1;
              }
         }
  }

void scriere()
  {
   fout=fopen(outfile,"w");
   solve();
   while(suma[g]==-1)
        g--;
   fprintf(fout,"%d %d\n",g,suma[g]);

   if(n<=1705 && g<=1705)
     {
      rucsac();
      solution2();
     }

   fclose(fout);
  }


int main()
{
//start=clock();
citire();
scriere();
return 0;
}