Cod sursa(job #1294892)

Utilizator RaduVisanRadu Visan RaduVisan Data 18 decembrie 2014 14:02:41
Problema Lapte Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.43 kb
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;

const int NMAX = 110, INF = 0x3f3f3f3f;

int N, L, A[NMAX], B[NMAX], Dp[NMAX][NMAX], Prev[NMAX][NMAX], Total;

bool Check(int T)
{
    for(int i = 0; i < NMAX; ++ i)
        for(int j = 0; j < NMAX; ++ j)
            Dp[i][j] = -INF, Prev[i][j] = 0;

    Dp[0][0] = 0;
    for(int i = 0; i < N; ++ i)
        for(int j = 0; j <= L; ++ j)
            for(int k = 0; j + k <= L && k * A[i + 1] <= T; ++ k)
                if(Dp[i][j] + (T - k * A[i + 1]) / B[i + 1] > Dp[i + 1][j + k])
                    Dp[i + 1][j + k] = Dp[i][j] + (T - k * A[i + 1]) / B[i + 1],
                    Prev[i + 1][j + k] = j;

    return Dp[N][L] >= L;
}

void Print(int X, int Y)
{
    if(X == 0)
    {
        printf("%i\n", Total);
        return ;
    }

    Print(X - 1, Prev[X][Y]);

    int TotalA = Y - Prev[X][Y], TotalB = (Total - TotalA * A[X]) / B[X];
    printf("%i %i\n", TotalA, TotalB);
}

int main()
{
    freopen("lapte.in", "r", stdin);
    freopen("lapte.out", "w", stdout);

    scanf("%i %i", &N, &L);
    for(int i = 1; i <= N; ++ i)
        scanf("%i %i", &A[i], &B[i]);

    int Left = 1, Right = 100, Mid, Ans;
    while(Left <= Right)
    {
        Mid = (Left + Right) / 2;
        if(Check(Mid)) Ans = Mid, Right = Mid - 1;
        else Left = Mid + 1;
    }

    Check(Ans);

    Total = Ans;

    Print(N, L);
}