Cod sursa(job #645421)

Utilizator ChallengeMurtaza Alexandru Challenge Data 9 decembrie 2011 16:30:41
Problema Lapte Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.67 kb
#include <fstream>
#include <cstring>

using namespace std;

const char InFile[]="lapte.in";
const char OutFile[]="lapte.out";
const int MaxN=128;
const int INF=1<<30;

ifstream fin(InFile);
ofstream fout(OutFile);

int N,L,T,A[MaxN],B[MaxN],D[MaxN][MaxN],P[MaxN][MaxN],solA[MaxN],solB[MaxN];

inline bool isSol(int T)
{
	for(register int i=1;i<=N;++i)
	{
		for(register int j=0;j<=L;++j)
		{
			D[i][j]=-INF;
		}
	}
	for(int i=1;i<=N;++i)
	{
		for(register int j=0;j<=L;++j)
		{
			for(register int k=0;k<T/B[i] && j>=k;++k)
			{
				int LA=(T-k*B[i])/A[i];
				if(i>1 || j-k==0)
				{
					D[i][j]=max(D[i][j],D[i-1][j-k]+LA);
				}
			}
		}
	}
	return D[N][L]>=L;
}

inline bool makeSol(int T)
{
	for(register int i=1;i<=N;++i)
	{
		for(register int j=0;j<=L;++j)
		{
			D[i][j]=-INF;
		}
	}
	for(int i=1;i<=N;++i)
	{
		for(register int j=0;j<=L;++j)
		{
			for(register int k=0;k<T/B[i] && j>=k;++k)
			{
				if(i>1 || j-k==0)
				{
					int x=D[i-1][j-k]+(T-k*B[i])/A[i];
					if(D[i][j]<x)
					{
						D[i][j]=x;
						P[i][j]=j-k;
					}
				}
			}
		}
	}
	return D[N][L]>=L;
}

void rec(int i, int j)
{
	if(i==0)
	{
		return;
	}
	solA[i]=D[i][j]-D[i-1][P[i][j]];
	solB[i]=(T-solA[i]*A[i])/B[i];
	rec(i-1,P[i][j]);
}

int main()
{
	fin>>N>>L;
	for(register int i=1;i<=N;++i)
	{
		fin>>A[i]>>B[i];
	}
	fin.close();
	
	int p=0,u=MaxN*MaxN*2;
	while(p<=u)
	{
		int m=p+((u-p)>>1);
		if(isSol(m))
		{
			T=m;
			u=m-1;
		}
		else
		{
			p=m+1;
		}
	}
	makeSol(T);
	rec(N,L);
	fout<<T<<"\n";
	for(register int i=1;i<=N;++i)
	{
		fout<<solA[i]<<" "<<solB[i]<<"\n";
	}
	fout.close();
	return 0;
}