Cod sursa(job #350765)
#include <algorithm>
#include <stdio.h>
#define MAX 128
#define mp make_pair
#define f first
#define s second
using namespace std;
int n, l, minT;
int ta[MAX], tb[MAX], fol[MAX];
int matCant[MAX][MAX], matDrum[MAX][MAX], matRec[MAX][MAX];
inline int incearca(int t)
{
for (int i = 0; i <= n; i++)
{
for (int a = 0; a <= l; a++)
matCant[i][a] = -1;
matCant[i][0] = 0;
}
for (int i = 1; i <= n; i++)
{
memcpy(matCant[i], matCant[i - 1], sizeof(matCant[i - 1]));
for (int folA = 0; folA <= t / ta[i]; folA++)
{
int folB = (t - folA * ta[i]) / tb[i];
for (int a = l; a - folA >= 0; a--)
if (matCant[i - 1][a - folA] != -1)
if (matCant[i][a] < matCant[i - 1][a - folA] + folB)
{
matCant[i][a] = matCant[i - 1][a - folA] + folB;
matDrum[i][a] = folA;
}
}
}
if (matCant[n][l] >= l)
return 1;
return 0;
}
inline void cautaBin(int fr, int ls)
{
if (fr > ls)
return;
int med = (fr + ls) / 2;
if (incearca(med))
{
minT = med;
memcpy(matRec, matDrum, sizeof(matRec));
cautaBin(fr, med - 1);
}
else cautaBin(med + 1, ls);
}
int main()
{
freopen("lapte.in", "r", stdin);
freopen("lapte.out", "w", stdout);
scanf("%d %d", &n, &l);
for (int i = 1; i <= n; i++)
scanf("%d %d", &ta[i], &tb[i]);
cautaBin(0, 64);
printf("%d\n", minT);
for (int a = l, i = n; i; a -= matRec[i][a], i--)
fol[i] = matRec[i][a];
int fa = 0, fb = 0;
for (int i = 1; i <= n; i++)
{
printf("%d %d\n", fol[i], (minT - ta[i] * fol[i]) / tb[i]);
fa += fol[i];
fb += (minT - ta[i] * fol[i]) / tb[i];
}
if (fa < l || fb < l)
for (; ; );
fclose(stdin);
fclose(stdout);
return 0;
}