Cod sursa(job #1198721)

Utilizator dariusdariusMarian Darius dariusdarius Data 16 iunie 2014 21:14:11
Problema Lapte Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.76 kb
#include <cstring>

#include <algorithm>
#include <fstream>
#include <vector>
using namespace std;
const int MAX_N = 105;
const int INFINITE = 1000000000;

int n, l, a[MAX_N], b[MAX_N];
int dp[MAX_N][MAX_N];
int drunk[MAX_N][MAX_N];

inline void run_dp(int time) {
    memset(dp, 0, sizeof dp);
    for(int i = 1; i <= l; ++ i) {
        dp[0][i] = -INFINITE;
    }
    for(int i = 1; i <= n; ++ i) {
        for(int j = 0; j <= l; ++ j) {
            drunk[i][j] = 0;
            dp[i][j] = dp[i - 1][j] + time / b[i];
            for(int k = 0; k <= j && k * a[i] <= time; ++ k) {
                if(dp[i][j] < dp[i - 1][j - k] + (time - k * a[i]) / b[i]) {
                    dp[i][j] = dp[i - 1][j - k] + (time - k * a[i]) / b[i];
                    drunk[i][j] = k;
                }
            }
        }
    }
}

int main() {
    ifstream fin("lapte.in");
    ofstream fout("lapte.out");
    fin >> n >> l;
    for(int i = 1; i <= n; ++ i) {
        fin >> a[i] >> b[i];
    }
    int left = 1, right = l * (a[1] + b[1]), last = l * (a[1] + b[1]);
    while(left <= right) {
        int middle = (left + right) / 2;
        run_dp(middle);
        if(dp[n][l] >= l) {
            last = middle;
            right = middle - 1;
        } else {
            left = middle + 1;
        }
    }
    run_dp(last);
    fout << last << "\n";
    int x = l;
    vector< pair<int, int> > solution;
    for(int i = n; i >= 1; -- i) {
        int drink_a = drunk[i][x];
        int drink_b = (last - drink_a * a[i]) / b[i];
        solution.push_back(make_pair(drink_a, drink_b));
        x -= drunk[i][x];
    }
    for(vector< pair<int, int> > :: reverse_iterator it = solution.rbegin(); it != solution.rend(); ++ it) {
        fout << it->first << " " << it->second << "\n";
    }
    return 0;
}