Cod sursa(job #2871814)

Utilizator andrei_marciucMarciuc Andrei andrei_marciuc Data 15 martie 2022 19:49:19
Problema Lapte Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.79 kb
#include <fstream>
#include <cstring>
#define MAX 101
using namespace std;

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

struct Andrei {
    int a, b;
};

Andrei v[ MAX + 2 ];
int a[ MAX + 2 ], b[ MAX + 2 ], n, l;
int dp[ MAX + 2 ][ MAX + 2 ];
int rec[ MAX + 2 ][ MAX + 2 ];
int rez[ MAX + 2 ][ MAX + 2 ];

bool ok( int val ) {
    for( int i = 1; i <= l; i++ ) 
        dp[ 0 ][ i ] = -1000000;
    for( int i = 1; i <= n; i++ )
        for( int j = 0; j <= l; j++ ) {
            //printf( "%d\n", b[ i ] );
            dp[ i ][ j ] = dp[ i - 1 ][ j ] + val / b[ i ];
            rec[ i ][ j ] = 0;
            for( int k = j - 1; k >= 0; k-- ) {
                int need = ( val - ( j - k ) * a[ i ] ) / b[ i ];
                if( val - ( j - k ) * a[ i ] < 0 )
                    break;
                
                if( dp[ i ][ j ] < dp[ i - 1 ][ k ] + need ) {
                    dp[ i ][ j ] = dp[ i - 1 ][ k ] + need;
                    rec[ i ][ j ] = j - k;
                }
            }
        }
    return ( dp[ n ][ l ] >= l );
}
    

int main()
{
    cin >> n >> l;
    for( int i = 1; i <= n; i++ )
        cin >> a[ i ] >> b[ i ];

    int left = 1, sol;
    int right = 3456;
    while( left <= right ) {
        int med = ( left + right ) >> 1;
        if( ok( med ) ) {
            right = med - 1;
            sol = med;
            memcpy( rez, rec, sizeof(rec) );
        } else left = med + 1;
        memset( dp, 0, sizeof( dp ) );
        memset( rec, 0, sizeof( rec ) );
    }

    cout << sol << '\n';
    int val = l;
    for( int i = n; i >= 1; i-- ) {
        v[ i ] = { rez[ i ][ val ], ( sol - a[ i ] * rez[ i ][ val ] ) / b[ i ] };
        val -= rez[ i ][ val ];
    }

    for( int i = 1; i <= n; i++ )
        cout << v[ i ].a << ' ' << v[ i ].b << '\n';
    return 0;
}