Cod sursa(job #18582)

Utilizator m_dersidanDersidan Mihai m_dersidan Data 18 februarie 2007 12:41:47
Problema Ghiozdan Scor 54
Compilator cpp Status done
Runda preONI 2007, Runda 2, Clasele 11-12 Marime 1.59 kb
# include <stdio.h>
# include <stdlib.h>

# define  _fin  "ghiozdan.in"
# define  _fout "ghiozdan.out"

# define  maxn  20002
# define  maxw  75002


int a[maxw], f[maxw], o[maxn], n, g;
int gmax, nmin;
int sol[maxn];


void readf()
{
	freopen(_fin, "r", stdin);
	int i;
	
	for (scanf("%d%d", &n, &g), i=1; i<=n; i++) scanf("%d", o+i);
}

int poz(int st, int dr, int a[])
{
	int x = a[st];

	while ( st < dr ) {	
		while ( st < dr && a[dr] >= x ) dr--; a[st] = a[dr];
		while ( st < dr && a[st] <= x ) st++; a[dr] = a[st];  
	}
	
	a[st] = x; return st;
}

void qs(int st, int dr, int a[])
{
	int p = rand() % (dr-st+1) + st, m;
	
	if ( p != st ) a[st] ^= a[p] ^= a[st] ^= a[p];
	m = poz(st, dr, a);
	
	if ( st < m ) qs(st, m-1, a);
	if ( m < dr ) qs(m+1, dr, a);
}

void solve()
{
	int i, j, dr=0;

	qs(1, n, o);
	
	for (i=1; i<=n; i++)
	{
		for (j=dr; j>=1; j--)
			if ( a[j] )
				if ( ( !a[ j+o[i] ] || a[ j+o[i] ] > a[j]+1 ) && j+o[i] <= g )
					a[ j+o[i] ] = a[j]+1,
					f[ j+o[i] ] = j;

		if ( !a[ o[i] ] )
		{
			a[ o[i] ] = 1;
			f[ o[i] ] = 0;
		}

		dr += o[i];
		if ( dr > g ) dr = g;
	}
	
	// cauta Gmax si Nmin
	for (j=g; j>=0 && !gmax; j--)
		if ( a[j] )
		{
			gmax = j;
			nmin = a[j];
		}
	
	// create the solution
	for (j=gmax; f[j]; j = f[j])
		sol[ ++sol[0] ] = j - f[j];
		
	sol[ ++sol[0] ] = j;
}

void writef()
{
	freopen(_fout, "w", stdout);
	int i;
	
	for (printf("%d %d\n", gmax, nmin), i=1; i<=sol[0]; i++)
		 printf("%d\n", sol[i]);
}

int main()
{
	readf();
	solve();
	writef();
	
	return 0;
}