Cod sursa(job #1737075)

Utilizator Burbon13Burbon13 Burbon13 Data 3 august 2016 12:14:41
Problema Lapte Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.36 kb
#include <cstdio>

using namespace std;

const int nmx = 102;

int oameni, lapte_de_baut;
int timp_a[nmx], timp_b[nmx];
int dp[nmx][nmx], mutare[nmx][nmx];
int copie_dp[nmx][nmx], copie_mutare[nmx][nmx], timp_cautat;
int litri_a[nmx], litri_b[nmx];

void citire()
{
    scanf("%d %d", &oameni, &lapte_de_baut);
    for(int i = 1; i <= oameni; ++i)
        scanf("%d %d", &timp_a[i], &timp_b[i]);
}

void curatare()
{
    for(int i = 0; i < nmx; ++i)
        for(int j = 0; j < nmx; ++j)
        {
            dp[i][j] = 0;
            mutare[i][j] = 0;
        }
}

bool timp_bun(int timp)
{
    curatare();

    int pos = 0;

    while((timp - timp_a[1]*pos) / timp_b[1] > 0)
    {
        dp[1][pos] = (timp - timp_a[1]*pos) / timp_b[1];
        ++ pos;
    }

    for(int i = 2; i <= oameni; ++i)
        for(int j = 0; j <= lapte_de_baut; ++j)
            for(int lapte = 0; lapte <= lapte_de_baut; ++lapte)
            {
                if(lapte * timp_b[i] <= timp && dp[i][j] < dp[i-1][j] + lapte) /// bea lapte litri de B
                {
                    dp[i][j] = dp[i-1][j] + lapte;
                    mutare[i][j] = 0;
                }
                if(j >= lapte && lapte * timp_a[i] <= timp && dp[i][j] < dp[i-1][j-lapte]) /// bea lapte litri de A
                {
                    dp[i][j] = dp[i-1][j-lapte];
                    mutare[i][j] = lapte;
                }
                if(j >= lapte && mutare[i][j-lapte] == 0 && timp >= lapte * timp_a[i] + timp_b[i] * (dp[i][j-lapte] - dp[i-1][j-lapte]) && dp[i][j] < dp[i][j-lapte])
                {
                    dp[i][j] = dp[i][j-lapte];
                    mutare[i][j] = -lapte;
                }

            }

    if(dp[oameni][lapte_de_baut] >= lapte_de_baut)
        return 1;

    return 0;
}

void memoreaza(int timp)
{
    timp_cautat = timp;
    for(int i = 0; i < nmx; ++i)
        for(int j = 0; j < nmx; ++j)
        {
            copie_dp[i][j] = dp[i][j];
            copie_mutare[i][j] = mutare[i][j];
        }
}

void cautare_binara()
{
    int stanga = 1, dreapta = 100;

    while(stanga <= dreapta)
    {
        int mijloc = (stanga + dreapta) / 2;

        if(timp_bun(mijloc))
        {
            memoreaza(mijloc);
            dreapta = mijloc - 1;
        }
        else
        {
            stanga = mijloc + 1;
        }
    }

}

void reconstituire()
{
    int i = oameni, j = lapte_de_baut;

    while(i > 1)
    {
        if(copie_mutare[i][j] > 0) /// a baut A
        {
            int baut = copie_mutare[i][j];
            litri_a[i] = baut;
            j -= baut;
            -- i;
        }
        else if(copie_mutare[i][j] == 0)              /// a baut B
        {
            int baut = dp[i][j] - dp[i-1][j];
            litri_b[i] = baut;
            -- i;
        }
        else
        {
            int baut = -copie_mutare[i][j];
            litri_a[i] = baut;
            j -= baut;
        }
    }

    litri_a[1] = j;
    litri_b[1] = dp[1][j];
}

void afish()
{
    printf("%d\n", timp_cautat);

    for(int i = 1; i <= oameni; ++i)
        printf("%d %d\n", litri_a[i], litri_b[i]);
}

int main()
{
    freopen("lapte.in", "r", stdin);
    freopen("lapte.out", "w", stdout);
    citire();
    cautare_binara();
    reconstituire();
    afish();
}