Cod sursa(job #18635)

Utilizator georgianaGane Andreea georgiana Data 18 februarie 2007 12:51:45
Problema Ghiozdan Scor 50
Compilator cpp Status done
Runda preONI 2007, Runda 2, Clasele 11-12 Marime 1.79 kb
#include <stdio.h>
#include <string.h>

#define inf 20001
int n,cap,gr[20001],a[2][75001];
char iau[201][75001];

int main()
{
   freopen("ghiozdan.in","r",stdin);
   freopen("ghiozdan.out","w",stdout);
   scanf("%d %d",&n,&cap);
   int greu=0;
   for (int i=1;i<=n;i++)
      {
         scanf("%d",&gr[i]);
         if (greu<cap) greu+=gr[i];
      }

   if (greu<cap) cap=greu;

   if (n<=200)
     {
        int act=0, last=1;
        for (int g=0;g<=cap;g++) a[act][g]=inf;
        a[act][0]=0;
        for (int i=1;i<=n;i++)
            {
               act=1-act; last=1-last;
               for (int g=0;g<=cap;g++)
                  {
                     a[act][g]=a[last][g];
                     iau[i][g]=0;
                     if (g>=gr[i] && a[act][g]>a[last][g-gr[i]])
                        a[act][g]=a[last][g-gr[i]]+1,
                        iau[i][g]=1;
                  }
          }
        while (a[act][cap]==inf) cap--;
        printf("%d %d\n",cap,a[act][cap]);
        while (n>0)
          {
             if (iau[n][cap])
               {
                  printf("%d\n",gr[n]);
                  cap-=gr[n];
               }
             n--;
          }
        fclose(stdout);
        return 0;
     }

   int act=0, last=1;
   for (int g=0;g<=cap;g++) a[act][g]=inf;
   a[act][0]=0;
   for (int i=1;i<=n;i++)
      {
         act=1-act; last=1-last;
         for (int g=0;g<=cap;g++)
            {
               a[act][g]=a[last][g];
               if (g>=gr[i] && a[act][g]>a[last][g-gr[i]])
                  a[act][g]=a[last][g-gr[i]]+1;
            }
      }
   while (a[act][cap]==inf) cap--;

   printf("%d %d\n",cap,a[act][cap]);
   for (int i=1;i<=a[act][cap];i++) printf("%d\n",gr[i]);
   fclose(stdout);
   return 0;
}