Cod sursa(job #19102)

Utilizator bogdan2412Bogdan-Cristian Tataroiu bogdan2412 Data 18 februarie 2007 19:16:55
Problema Ghiozdan Scor 24
Compilator c Status done
Runda Arhiva de probleme Marime 1.36 kb
#include <stdio.h>
#include <string.h>

#define MAX 200
#define MAXG 75005

#define BUC 14

int N, G;
int c[MAX + 1];

int best[MAX / BUC + 5][MAXG];

int bestm[BUC][MAXG];

int d[MAX + 1], p[MAX + 1], dl, dr;

void initdeque() { dl = 0; dr = -1; }

void adddeque(int val, int poz, int L)
{
	while ( dr >= dl && d[dr] + poz - p[dr] >= val ) dr--;
	d[++dr] = val;
	p[dr] = poz;
	if (poz - p[dl] > L)
		dl++;
}

void calculateline( int nxt[], int prv[], int cur )
{
	int i, r;
	//nxt[i] = max( prv[i - x * cur] + x | x <= c[cur] && x <= i / cur )
	//deque for every different remainder
	for (r = 0; r < cur; r++)
	{
		initdeque();
		for (i = r; i <= G; i += cur)
		{
			adddeque( prv[i], i / cur, c[cur] );
			nxt[i] = d[dl] + i / cur - p[dl];
		}
	}
}

int main()
{
	freopen("ghiozdan.in", "rt", stdin);
	freopen("ghiozdan.out", "wt", stdout);

	int i, j;
	for (scanf("%d %d", &N, &G), i = 0; i < N; i++)
	{
		scanf("%d", &j);
		c[j]++;
	}

	memset(bestm[0], 0x3f, sizeof(bestm[0]));
	bestm[0][0] = 0;

	for (i = 1; i <= MAX; i++)
	{
		calculateline( bestm[i & 1], bestm[!(i & 1)], i );
		if (i % BUC == MAX % BUC)
		{
			int poz = (i - (MAX % BUC)) / BUC;
			memcpy( best[poz], bestm[i & 1], sizeof( best[poz] ) );
		}
	}

	int poz = (MAX - (MAX % BUC)) / BUC;

	for (i = G; i >= 0 && best[poz][i] == 0x3f3f3f3f; i--);
	printf("%d %d\n", i, best[poz][i]);

	//TODO reconstituire

	return 0;
}