Cod sursa(job #1107)

Utilizator m_dersidanDersidan Mihai m_dersidan Data 12 decembrie 2006 18:33:13
Problema Lapte Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.02 kb
# include <stdio.h>
# include <string.h>

# define  maxn  102

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


int ca[maxn], cb[maxn], n, l, best[maxn][maxn], from[maxn][maxn], last[maxn][maxn];
int sol;


void readf()
{
	FILE *fin = fopen(_fin, "r");
	int i;
	
	for (fscanf(fin, "%d %d", &n, &l), i=1; i<=n; i++)
		 fscanf(fin, "%d %d", ca+i, cb+i);
		 
	fclose(fin);
}

inline int max(int a, int b)
{
	return a>b?a:b;
}
inline int min(int a, int b)
{
	return a<b?a:b;
}

int	candrink(int t)
{
	int i, j, qa, maxa, aux;

	memset(best, 0xff, sizeof(best));
//	memset(from, 0, sizeof(from));

	for (maxa=t/ca[1], i=0; i<=maxa; i++)
		best[1][i] = ( t - i*ca[1] ) / cb[1];	// cat lapte b poate sa bea maxim
		
	for (i=2; i<=n; i++)
		for (qa=0; qa <= l; qa++)
		{
			// poate bea intre 0->min(qa, t/ca[i]) lapte a
			for (j=0, maxa = min(qa, t/ca[i]); j<=maxa; j++)
				if ( best[i-1][qa-j] != -1 )
				if ( (aux=best[i-1][qa-j] + ( t-j*ca[i] ) / cb[i] ) > best[i][qa] )
					best[i][qa] = aux, from[i][qa] = qa-j;
		}
		
	return ( best[n][l] >= l );
}

void solve()
{
	// caut binar timpul
	int mina, minb, tmax, t, step, i;
	
	for (mina=ca[1], minb=cb[1], i=2; i<=n; i++)
		 mina = ca[i] < mina ? ca[i] : mina,
		 minb = cb[i] < minb ? cb[i] : minb;
		 
	tmax = l * mina + l * minb;
	
	for (step=1; step<tmax; step<<=1);

	for (t=tmax; step; step>>=1)
		if ( t - step >= 1 )
			if ( candrink(t - step) )
				t -= step,
				memcpy(last, from, sizeof(from));
				
	sol = t,
	memcpy(from, last, sizeof(last));
}

void writef()
{
	int i, act, total=l, aux;
	int q[maxn][2];
	FILE *fout = fopen(_fout, "w");

	memset(q, 0, sizeof(q));

	for (i=n, act=from[n][l]; i>=1; i--)
		q[i][0] = total-act,
		total = act,
		q[i][1] = ( sol-q[i][0] * ca[i] ) / cb[i],
		act = from[i-1][act];

	for (fprintf(fout, "%d\n",sol),i=1; i<=n; i++)
	     fprintf(fout, "%d %d\n", q[i][0], q[i][1]);

	fclose(fout);
}

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