Cod sursa(job #1480609)

Utilizator DorelBarbuBarbu Dorel DorelBarbu Data 2 septembrie 2015 21:19:04
Problema Lapte Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <iostream>
#include <fstream>
#include <deque>
using namespace std;

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

const int MAXN = 100, INF = 2000000000;

int a[MAXN+1], b[MAXN+1], N, L, dp[MAXN+1][MAXN+1], cnt[MAXN+1][MAXN+1];

void citire()
{
    in>>N>>L;

    for(int i = 1; i <= N; i++)
        in>>a[ i ]>>b[ i ];
}

void dinamica(int T)
{
    dp[ 0 ][ 0 ] = 0;

    for(int i = 0; i <= N; i++)
        for(int j = 0; j <= MAXN; j++)
        {
            dp[ i ][ j ] = 0;
            cnt[ i ][ j ] = 0;
        }


    for(int i = 0; i <= MAXN && T - i*a[ 1 ] >= 0; i++)
    {
        int q = ( T - i*a[ 1 ] ) / b[ 1 ];
        dp[ 1 ][ i ] = q;
        cnt[ 1 ][ i ] = i;
    }

    for(int i = 2; i <= N; i++)
    {
        for(int j = 0; j <= MAXN; j++)
        {
            for(int k = 0; j - k >= 0 && T - k*a[ i ] >= 0; k++)
            {
                int q = ( T - k*a[ i ] ) / b[ i ];

                if( dp[ i ][ j ] < dp[ i - 1 ][ j - k ] + q )
                {
                    dp[ i ][ j ] = dp[ i - 1 ][ j - k ] + q;
                    cnt[ i ][ j ] = k;
                }
            }
        }
    }
}

deque <int> sol;

void rec(int i, int j, int T)
{

    if(i || j)
    {
        //sol.push_back( cnt[ i ][ j ] );
        //i--; j -= cnt[ i ][ j ];
        rec( i - 1, j - cnt[ i ][ j ], T );
        out<<cnt[ i ][ j ]<<' '<<( T - cnt[ i ][ j ]*a[ i ] ) / b[ i ]<<endl;
    }

    //for(int i = 0; i < N; i++)
        //out<<sol[ i ]<<' '<<( T - sol[ i ]*a[ i + 1 ] ) / b[ i + 1 ]<<endl;
}

void solutie(int i, int j, int T)
{
    while( i > 0 || j > 0 )
    {
        sol.push_front( cnt[ i ][ j ] );
        int aux = cnt[ i ][ j ];
        i = i - 1; j = j - aux;
    }

    for(int i = 0; i < N; i++)
        out<<sol[ i ]<<' '<<( T - sol[ i ]*a[ i + 1 ] ) / b[ i + 1 ]<<endl;
}

int answer, Q;

void solve(int left, int right)
{
    if( left > right )
        return;

    int m = ( left + right ) / 2;

    dinamica( m );


    bool ok = false;

    for(int i = L; i <= MAXN; i++)
        if( dp[ N ][ i ] >= L )
        {
            answer = m;
            Q = i;
            ok = true;
            break;
        }


    if( ok == true )
    {
        answer = m;
        solve(left, m - 1);
    }
    else solve(m + 1,right);
}



int main()
{
    citire();

    solve(0, a[ 1 ]*L + b[ 1 ]*L);
    out<<answer<<endl;
    dinamica( answer );
    /*
    for(int i = 1; i <= N; i++)
    {
        for(int j = 0; j <= L; j++)
            cout<<dp[ i ][ j ]<<' ';
        cout<<endl;
    }*/

    solutie(N,L,answer);

    return 0;
}