Cod sursa(job #34761)

Utilizator unholyfrozenCostea Andrei unholyfrozen Data 21 martie 2007 12:53:36
Problema Ghiozdan Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include<stdio.h>

#define NMAX 210
#define GMAX 75100

void read();
void gorec(int a, int b, int x);

int N, G, nr[NMAX], A[2][GMAX], B[2][GMAX];
int Q[GMAX], vf, bf;

int main()
{
	freopen("ghiozdan.in", "r", stdin);
     freopen("ghiozdan.out", "w", stdout);

     read();
	return 0;
}

void read()
{
	int a, i, ok, j, k;
     
	scanf("%d%d", &N, &G);
     for(i = 0; i < N; i++)
     {
     	scanf("%d", &a);
          nr[a]++;
     }

     for(i = 1; i <= G; i++)
     A[0][i] = GMAX;
     
     for(i = 1, ok = 1; i <= 200; i++, ok = !ok)
     {
          for(j = 0; j < i; j++)
          {
          	bf = 0, vf = -1;
		for(k = 0; k * i + j <= G; k++)
          {
          	A[ok][k * i + j] = GMAX;
          	while(vf >= bf && k - Q[bf] > nr[i])
               bf++;
			while(vf >= bf && A[!ok][Q[vf] * i + j] + k - Q[vf] >= A[!ok][k * i + j])
			vf--;
               Q[++vf] = k;
               if(A[!ok][Q[bf] * i + j] != GMAX)
               {
	               A[ok][k * i + j] = A[!ok][Q[bf] * i + j] + k - Q[bf];
                    B[ok][k * i + j] = (i <= 100) ? k * i + j : B[!ok][Q[bf] * i + j];
               }
          }
          }
     }
     for(i = G; i >= 0; i--)
     if(A[!ok][i] != GMAX) break;
     
     printf("%d %d\n", i, A[!ok][i]);
     j = B[!ok][i];
     gorec(1, 100, B[!ok][i]);
     gorec(101, 200, i - j);
}

void gorec(int a, int b, int x)
{
	int i, j, k, ok, old;
     
	if(a > b) return;

     if(!x) return;
     
	if(a == b)
     {
		for(; x; x -= a)
          printf("%d\n", a);
          return;
     }
     for(i = 1; i <= G; i++)
     A[0][i] = GMAX;
     
     for(i = a, ok = 1; i <= b; i++, ok = !ok)
     {
          for(j = 0; j < i; j++)
          {
          	bf = 0, vf = -1;
		for(k = 0; k * i + j <= x; k++)
          {
          	A[ok][k * i + j] = GMAX;
          	while(vf >= bf && k - Q[bf] > nr[i])
               bf++;
			while(vf >= bf && A[!ok][Q[vf] * i + j] + k - Q[vf] >= A[!ok][k * i + j])
			vf--;
               Q[++vf] = k;
               if(A[!ok][Q[bf] * i + j] != GMAX)
               {
	               A[ok][k * i + j] = A[!ok][Q[bf] * i + j] + k - Q[bf];
                    B[ok][k * i + j] = (i <= (a + b) / 2) ? k * i + j : B[!ok][Q[bf] * i + j];
               }
          }
          }
     }
     
     old = B[!ok][x];
     gorec(a, (a + b) / 2, B[!ok][x]);
     gorec((a + b) / 2 + 1, b, x - old);
}