Cod sursa(job #687589)

Utilizator PetcuIoanPetcu Ioan Vlad PetcuIoan Data 22 februarie 2012 16:38:48
Problema Lapte Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.3 kb
#include<stdio.h>
#include<assert.h>

#include<algorithm>

using namespace std;

const int knmax=105;
int n, l, sol, speeda[knmax], speedb[knmax], dranka[knmax], drankb[knmax], d[knmax][knmax][knmax];

struct recon {
    int x, y, z;
    recon (){};
};

recon father[knmax][knmax][knmax];

void read(){
    assert(freopen("lapte.in","r",stdin) != NULL);
    scanf("%d%d",&n ,&l);
    int i;
    for(i = 1; i <= n; ++i)
        scanf("%d%d",&speeda[i] ,&speedb[i]);
}

void init(){
    int i, j, k;
    for(i = 0; i <= n; ++i)
        for(j = 0; j <= l; ++j)
            for(k = 0; k <= l; ++k)
                d[i][j][k] = 0;
    d[0][0][0]=1;
}

recon make_recon(int ind1, int ind2, int ind3){
    recon x;
    x.x = ind1;
    x.y = ind2;
    x.z = ind3;
    return x;
}

int check(int secconds){
    int i, j, k, m;
    init();
    for(i = 1; i <= n; ++i)
        for(j = 0; j <= l; ++j)
            for(k = 0; k <= l; ++k)
                if(d[i - 1][j][k])
                    for(m = 0; m <= secconds/speeda[i]; ++m)
                        d[i][min(j + m , l)][min(k + (secconds - speeda[i] * m) / speedb[i] , l)] = 1;
    return d[n][l][l];
}

void get_sol(){
    int left = 1, right = knmax, mid, last;
    while(left <= right){
        mid = (left + right) / 2;
        if(check(mid)){
            right = mid - 1;
            last = mid;
        }
        else
            left = mid + 1;
    }
    sol = last;
}

void solve(){
    get_sol();
    init();
    int i, j, k, m;
    for(i = 1; i <= n; ++i)
        for(j = 0; j <= l; ++j)
            for(k = 0; k <= l; ++k)
                if(d[i - 1][j][k])
                    for(m = 0; m <= sol/speeda[i]; ++m){
                        d[i][min(j + m , l)][min(k + (sol - speeda[i] * m) / speedb[i] , l)] = 1;
                        father[i][min(j + m , l)][min(k + (sol - speeda[i] * m) / speedb[i] , l)] = make_recon(i-1, j, k);
                    }
    recon p = make_recon(n, l, l), aux;
    while(p.x != 0){
        aux = p;
        p = father[p.x][p.y][p.z];
        dranka[aux.x] = aux.y - p.y;
        drankb[aux.x] = aux.z - p.z;
    }
}

void write(){
    assert(freopen("lapte.out","w",stdout) != NULL);
    printf("%d\n",sol);
    int i;
    for(i = 1; i <= n; ++i)
        printf("%d %d\n",dranka[i] ,drankb[i]);
}

int main(){
    read();
    solve();
    write();
    return 0;
}