Cod sursa(job #742875)

Utilizator vendettaSalajan Razvan vendetta Data 1 mai 2012 21:35:19
Problema Lapte Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.79 kb
#include <fstream>
#include <iostream>

#define nmax 105

using namespace std;

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

int n, L, dp[nmax][nmax], a[nmax], b[nmax];
int drum[nmax][nmax];
struct{

    int x, y;

}rez[nmax];

void citeste(){

    f >> n >> L;
    for(int i=1; i<=n; i++) f >> a[i] >> b[i];

}

bool verif(int T){

    for(int i=0; i<=n; i++) for(int j=0; j<=L; j++) dp[i][j] = -(1<<29), drum[i][j] = 0;
    dp[0][0] = 0;

    // dp[i][j] = k;
    // k = nr de litri bauti de tipul B in timpul T, avand j litri de tipul A si folosind primii i concurenti
    for(int i=1; i<=n; i++){//i-au fiecare concurent
        for(int j=0; j<=L; j++){//pentru fiecare cantitate de lapte de tipul A
            for(int k=0; k<=T/a[i]; k++){//incerc sa continuu fiecare rezultat anterior
                int cost_a = k*a[i];//timpul pentru a avea k litri de tipul A;
                int litri_b = (T-cost_a)/b[i];//cati litri de tipul B poate sa bea al-i-lea concurent
                if (dp[i][j] < dp[i-1][max(0,j-k)] + litri_b){
                    dp[i][j] = dp[i-1][max(0,j-k)] + litri_b;
                    drum[i][j] = k;
                }
            }
        }
    }

    int nr = L;

    for(int i=n; i; i--){
        rez[i].x = drum[i][nr];
        rez[i].y = (T-rez[i].x*a[i])/b[i];
        nr -= rez[i].x;
    }

    if (dp[n][L] >= L) return 1;
    return 0;

}

int rezolva(){

    int st = 0;
    int dr = 105;
    int sol = 0;
    while (st <= dr){
        int mij = (st + dr) / 2;
        if ( verif(mij) ){
            sol = mij;
            dr = mij-1;
        }else st = mij+1;
    }

    return sol;

}

int main(){

    citeste();
    g << rezolva() << "\n";

    for(int i=1; i<=n; i++){
        g << rez[i].x << " " << rez[i].y << "\n";
    }

    f.close();
    g.close();

    return 0;

}