Cod sursa(job #645438)

Utilizator ChallengeMurtaza Alexandru Challenge Data 9 decembrie 2011 17:08:09
Problema Lapte Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.36 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],Pp[MaxN][MaxN],solA[MaxN],solB[MaxN];

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

void rec(int i, int j)
{
	if(i==0)
	{
		return;
	}
	solB[i]=Pp[i][j];
	solA[i]=(T-solB[i]*B[i])/A[i];
	rec(i-1,j-Pp[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;
			for(register int i=1;i<=N;++i)
			{
				for(register int j=1;j<=L;++j)
				{
					Pp[i][j]=P[i][j];
				}
			}
		}
		else
		{
			p=m+1;
		}
	}
	rec(N,L);
	fout<<T<<"\n";
	for(register int i=1;i<=N;++i)
	{
		fout<<solA[i]<<" "<<solB[i]<<"\n";
	}
	fout.close();
	return 0;
}