Cod sursa(job #1229714)

Utilizator smaraldaSmaranda Dinu smaralda Data 17 septembrie 2014 23:20:09
Problema Lapte Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.7 kb
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;

const int NMAX = 105;

int n, l, last, bmax[NMAX], a[NMAX], b[NMAX], solA[NMAX], solB[NMAX];
vector <int> lastInd[NMAX], lastA[NMAX];
bool vis[NMAX];

bool check (int t) {
    int i, j, B, A, pos, iA, lim;
    
    for(i = 1; i <= l; ++ i)
        bmax[i] = -1;
    bmax[0] = 0;
    lim = 0;
    
    for(i = 1; i <= n; ++ i)
        for(A = lim; A >= 0; -- A)
            if(bmax[A] != -1)
                for(iA = 1; a[i] * iA <= t && A + iA <= l; ++ iA) {
                    B = (t - a[i] * iA) / b[i];
                             
                    if(iA == 0) {
                        bmax[A] += B;
                        lastInd[A].push_back(i);
                        lastA[A].push_back(iA);

           //             fprintf(stderr, "\nind - %d, pos - %d, added - %d", i, iA, 0); 
                        continue;
                    }

                    pos = A + iA;

                    if(bmax[A] + B > bmax[pos]) {
                        bmax[pos] = bmax[A] + B;
                        
                        lastInd[pos].clear();
                        lastInd[pos].push_back(i);

                        lastA[pos].clear();
                        lastA[pos].push_back(iA);

             //           fprintf(stderr, "\ndel - %d\nind - %d, pos - %d, added - %d", pos, i, pos, iA);
                    }

                    lim = max(lim, pos);
                }
    return bmax[l] >= l;
}

void buildSol (int t) {
    int lastpos, pos, ind, i;

    memset(vis, 0, sizeof(vis));
    memset(solA, 0, sizeof(solA));
    memset(solB, 0, sizeof(solB));
    
    pos = lastpos = l;
    while(pos > 0) {
        for(i = 0; i < lastInd[pos].size(); ++ i) {
            ind = lastInd[pos][i];

            if(!vis[ind]) {
                solA[ind] = lastA[pos][i];
                solB[ind] = (t - solA[ind] * a[ind]) / b[ind];
                vis[ind] = 1;

                pos -= solA[ind];
            }
        }

        if(pos == lastpos)
            break;
        lastpos = pos;
    }
}

int bs (int right) {
    int left, mid, last;

    left = 1;
    while(left <= right) {
        mid = (left + right) / 2;
        if(check(mid)) {
            buildSol(mid);
            last = mid;
            //fprintf(stderr, "val = %d\n", mid);
            right = mid - 1;
        }
        else
            left = mid + 1;
    }

    return last;
}

int main() {
    freopen("lapte.in", "r", stdin);
    freopen("lapte.out", "w", stdout);
    int i;

    scanf("%d%d", &n, &l);
    for(i = 1; i <= n; ++ i)
        scanf("%d%d", &a[i], &b[i]);

    printf("%d\n", bs(100));
    for(i = 1; i <= n; ++ i)
        printf("%d %d\n", solA[i], solB[i]);
    return 0;
}