Cod sursa(job #22770)

Utilizator victorsbVictor Rusu victorsb Data 27 februarie 2007 14:16:20
Problema Lapte Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.43 kb
#include <cstdio>

#define Nmax 105
#define INF 1000000000
#define Min(a,b) ((a) < (b) ? (a) : (b))

int n, l;
int a[Nmax], b[Nmax], d[Nmax][Nmax], c1[Nmax][Nmax], c2[Nmax][Nmax], sa[Nmax][Nmax];

void citire()
{
    int i;
    scanf("%d %d\n", &n, &l);
    for (i = 1; i <= n; ++i)
        scanf("%d %d\n", &a[i], &b[i]);
}

void scrie(int n, int p)
{
    if (n == 0)
        return;
    scrie(n-1, sa[n][p]);
    printf("%d %d\n", c1[n][p], c2[n][p]);
}

void solve()
{
    int i, j, k, t, st, dr, sol = -1;
    
    st = 0; dr = 100;
    while (st <= dr)
    {
        t = (st + dr) >> 1;
        
        for (i = 0; i <= n; ++i)
            for (j = 0; j <= l; ++j)
                d[i][j] = -INF;
                    
        d[0][0] = 0;
        
        for (i = 1; i <= n; ++i)
        {
            for (j = 0; j <= l; ++j)
                d[i][j] = d[i-1][j];
            
            for (j = 0; j <= l; ++j)
                if (d[i-1][j] >= 0)
                    for (k = 0; k <= t / a[i]; ++k)
                        if (d[i][Min((j + k), l)] < d[i - 1][j] + (t - k * a[i]) / b[i])
                            d[i][Min((j + k), l)] = d[i - 1][j] + (t - k * a[i]) / b[i];
        }
        
        if (d[n][l] >= l)
        {
            sol = t;
            dr = t - 1;
        }
        else
            st = t + 1;
    }
    
    t = sol;
    for (i = 0; i <= n; ++i)
        for (j = 0; j <= l; ++j)
            d[i][j] = -INF;
                
    d[0][0] = 0;
    
    for (i = 1; i <= n; ++i)
    {
        for (j = 0; j <= l; ++j)
        {
            d[i][j] = d[i-1][j];
            c1[i][j] = 0;
            c2[i][j] = 0;
            sa[i][j] = j;
        }
        
        for (j = 0; j <= l; ++j)
            if (d[i-1][j] >= 0)
                for (k = 0; k <= t / a[i]; ++k)
                    if (d[i][Min((j + k), l)] < d[i - 1][j] + (t - k * a[i]) / b[i])
                    {
                        d[i][Min((j + k), l)] = d[i - 1][j] + (t - k * a[i]) / b[i];
                        c1[i][Min((j + k), l)] = k;
                        c2[i][Min((j + k), l)] = (t - k * a[i]) / b[i];
                        sa[i][Min((j + k), l)] = j;
                    }
    }
    
    printf("%d\n", sol);
    scrie(n, l);
}

int main()
{
    freopen("lapte.in", "r", stdin);
    freopen("lapte.out", "w", stdout);
    citire();
    solve();
    return 0;
}