Cod sursa(job #1559284)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 30 decembrie 2015 15:34:48
Problema Lapte Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.21 kb
/*
 * D[i][j] = cantitatea maxima de lapte de tip B
 * care se poate consuma de primele i persoane
 * impreuna cu cantitatea j de lapte de tip A
 */
#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 100;
const int NIL = -1;

int T[MAX_N + 1][2];

int D[MAX_N + 1][MAX_N + 1];
int B[MAX_N + 1][MAX_N + 1];
int A[MAX_N + 1][MAX_N + 1];

bool canPartition(const int &N, const int &L, const int &maxTime)
{
    int x = 0;

    D[0][0] = 0;
    for ( int i = 1; i <= N; ++i )
    {
       for ( int j = 1; j <= L; ++j )
            D[i][j] = NIL;

        int maxTake = maxTime / T[i][0];

        for ( int takeA = 1; takeA <= maxTake; ++takeA )
        {
            int takeB = ( maxTime - takeA * T[i][0] ) / T[i][1];
            for ( int j = x; j >= 0; --j )
            {
                if ( D[i - 1][j] != NIL )
                {
                    int newTakeB = takeB + D[i - 1][j];
                    int newTakeA = ( j + takeA > L ? L : j + takeA );

                    if ( D[i][newTakeA] < newTakeB )
                    {
                        D[i][newTakeA] = newTakeB;
                        A[i][newTakeA] = j;
                        B[i][newTakeA] = takeB;
                    }

                    if ( newTakeA > x )
                        x = newTakeA;
                }
            }
        }
    }
    return D[N][L] >= L;
}

void printSolution( const int N, const int L, ofstream &out, const int &maxTime )
{
    if (N != 0)
    {
        printSolution( N - 1, A[N][L], out, maxTime );
        out << ( maxTime - B[N][L] ) / T[N][0] << ' ' << B[N][L] << '\n';
    }
}

int main()
{
    ifstream in("lapte.in");
    ofstream out("lapte.out");
    in.tie(0);
    ios_base::sync_with_stdio(0);
    int N, L;

    in >> N >> L;
    for ( int i = 1; i <= N; ++i )
        in >> T[i][0] >> T[i][1];

    int lo = 0, hi = L + 1;
    while ( hi - lo > 1 )
    {
        int S = ( lo + hi ) / 2;

        if ( canPartition( N, L, S ) )
            hi = S;
        else
            lo = S;
    }

    out << hi << '\n';
    assert( canPartition( N, L, hi ) );
    printSolution( N, L, out, hi );
    out.close();
    return 0;
}