Cod sursa(job #2198781)

Utilizator tanasaradutanasaradu tanasaradu Data 25 aprilie 2018 13:24:55
Problema Lapte Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.05 kb
#include <bits/stdc++.h>
using namespace std;

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

const short NMAX = 105;

int dp[NMAX][NMAX] , n , L;

pair < int , int > a[NMAX][NMAX] , X[NMAX] , b[NMAX][NMAX];

/**
    dp[i][j] = t , t = Valoarea maxima a . i dp[i][j][t] sa fie true pentru un timp fixat
    , unde dp[i][j][t] = true , <=> timpul de a bea j litri din laptele A si t litri din laptele B <= timpul fixat
    Sirul dp[i][j][1] , dp[i][j][2] .. -> este ordonat descrescator
    (poate fi ori de forma (1 , 1  , 1 ... 1 , 0 , 0 , 0 ... 0)  sau (0 , 0 , ... 0) , )
*/


inline bool CHECK(int T)
{
    for(int i = 0 ; i <= n ; i++)
        for(int j = 0 ; j <= L ; j++)
            dp[i][j] = - 1e9;
    dp[0][0] = 0;
    for(int i = 1 ; i <= n ; i++)
    {
        for(int j = 0 ; j <= L ; j++)
            for(int k = 0 ; k <= j ; k++)
                if(k * X[i] . first <= T && dp[i][j] < dp[i - 1][j - k] + (T - k * X[i] . first) / X[i] . second )
        {
            dp[i][j] = dp[i - 1][j - k] + (T - k * X[i] . first) / X[i] . second;
            a[i][j] . first = k;
            a[i][j] . second = (T - k * X[i] . first) / X[i] . second;
        }
    }
    return (dp[n][L] >= L);
}


inline void REC(int i , int j)
{
    if(!i)
        return;
    REC(i - 1 , j - b[i][j] . first);
    fout <<  b[i][j] . first << " " << b[i][j] . second << "\n";
}


inline void SOLVE()
{
    int left = 1 , right = 1e6 , middle , poz , p , p1;
    while(left <= right)
    {
        middle = (left + right) / 2;
        if(CHECK(middle))
        {
            poz = middle;
            for(int i = 1 ; i <= n ; i++)
                for(int j = 0 ; j <= L ; j++)
                    b[i][j]  = a[i][j];
            right = middle - 1;
        }
        else left = middle + 1;
    }
    fout << poz << "\n";
    REC(n , L);
}

int main()
{
    fin >> n >> L;
    for(int i = 1 ; i <= n ; i++)
        fin >> X[i] . first >> X[i] . second;
    SOLVE();
    fin.close();
    fout.close();
    return 0;
}