Cod sursa(job #2910097)

Utilizator vlad2009Vlad Tutunaru vlad2009 Data 18 iunie 2022 14:48:35
Problema Lapte Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.11 kb
#include <fstream>
#include <vector>
#include <algorithm>
#define int long long

using namespace std;

const int MAX_N = 1e2;
const int INF = (1LL << 60);
int a[MAX_N + 1], b[MAX_N + 1];
int dp[MAX_N + 1][MAX_N + 1];
pair<int, int> sol[MAX_N + 1][MAX_N + 1];
vector<pair<int, int>> v;
int n, l;

bool check(int guess) {
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= l; j++) {
            dp[i][j] = -INF;
        }
    }
    dp[0][0] = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= l; j++) {
            for (int c = 0; c * a[i] <= guess && c <= j; c++) {
                int rem = guess - a[i] * c;
                dp[i][j] = max(dp[i][j], dp[i - 1][j - c] + rem / b[i]);
            }
        }
    }
    return dp[n][l] >= l;
}

void rec(int answer) {
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= l; j++) {
            dp[i][j] = -INF;
        }
    }
    dp[0][0] = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= l; j++) {
            for (int c = 0; c * a[i] <= answer && c <= j; c++) {
                int rem = answer - a[i] * c;
                if (dp[i][j] < dp[i - 1][j - c] + rem / b[i]) {
                    dp[i][j] = dp[i - 1][j - c] + rem / b[i];
                    sol[i][j] = {c, rem / b[i]};
                }
            }
        }
    }
    for (int i = n; i >= 1; i--) {
        v.push_back(sol[i][l]);
        l -= sol[i][l].first;
    }
}

int cb() {
    int st = 0, dr = (1 << 20), sol = 0;
    while (st <= dr) {
        int mijl = (st + dr) / 2;
        if (check(mijl)) {
            sol = mijl;
            dr = mijl - 1;
        } else {
            st = mijl + 1;
        }
    }
    return sol;
}

signed 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 answer = cb();
    fout << answer << "\n";
    rec(answer);
    reverse(v.begin(), v.end());
    for (auto it : v) {
        fout << it.first << " " << it.second << "\n";
    }
    return 0;
}