Cod sursa(job #823179)

Utilizator VincentVegaVincent Vega VincentVega Data 24 noiembrie 2012 18:30:53
Problema Lapte Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.85 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>
using namespace std;

ifstream fin("lapte.in");
ofstream fout("lapte.out");

int N, L, dp[111][111], v[111][111];
int a[111][2], sol[111][2];

inline bool check(int val)
{
	// dp[i][j] = k   daca bei j litrii din laptele A poti bea maxim k din laptele B, avand oamenii de la 1 la i
	memset(dp, -1, sizeof(dp));
	
	dp[0][0] = 0;
	for (int i = 1; i <= N; ++i)
	{
		for (int j = 0; j <= L; ++j)
		{
			int lim = j;
			if (i == 1) lim = 0;
			for (int k = 0; k <= lim; ++k)
			{
				if ((val - a[i][0] * (j - k)) >= 0)
				{
					dp[i][j] = max(dp[i][j], dp[i - 1][k] + (val - a[i][0] * (j - k)) / a[i][1]);
				}
			}
		}
	}
	
	if (dp[N][L] >= L) return true;
	return false;
}

void remake(int val)
{
	memset(dp, -1, sizeof(dp));
	
	dp[0][0] = 0;
	for (int i = 1; i <= N; ++i)
	{
		for (int j = 0; j <= L; ++j)
		{
			int lim = j;
			if (i == 1) lim = 0;
			for (int k = 0; k <= lim; ++k)
			{
				if ((val - a[i][0] * (j - k)) >= 0)
				{
					if (dp[i][j] < dp[i - 1][k] + (val - a[i][0] * (j - k)) / a[i][1])
					{
						dp[i][j] = dp[i - 1][k] + (val - a[i][0] * (j - k)) / a[i][1];
						v[i][j] = k;
					}
				}
			}
		}
	}
	
	int j = L;
	for (int i = N; i >= 1; --i)
	{
		sol[i][0] = j - v[i][j];
		sol[i][1] = (val - (sol[i][0] * a[i][0])) / a[i][1];
		j = v[i][j];
	}
}

inline int bs()
{
	int i = 111, cnt = 1 << 7;
	for (; cnt > 0; cnt >>= 1)
	{
		if (i - cnt > 0)
		{
			if (check(i - cnt))
			{
				i -= cnt;
			}
		}
	}
	
	return i;
}

int main()
{
	fin >> N >> L;
	for (int i = 1; i <= N; ++i)
	{
		fin >> a[i][0] >> a[i][1];
	}
	
	int val = bs();
	fout << val << '\n';
	remake(val);
	for (int i = 1; i <= N; ++i)
	{
		fout << sol[i][0] << ' ' << sol[i][1] << '\n';
	}
	
	fout.close();
	return 0;
}