Cod sursa(job #3254955)

Utilizator cristiWTCristi Tanase cristiWT Data 9 noiembrie 2024 10:45:53
Problema Problema rucsacului Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.23 kb
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int nmax = 5000, mod = 1e9 + 7, inf = 2e18;
int n, maxg, ans, prefp[nmax + 5], prefg[nmax + 5];

struct T {
    int p, g;
};
T a[nmax + 5];

bool ok(int i, int crtg, int crtp) {
    if (crtg > maxg) {
        return 0;
    }
    int best = 0;
    int l = i, r = n;
    while (l <= r) {
        int mid = (l + r) / 2;
        int g = prefg[mid] - prefg[i];
        int p = prefp[mid] - prefp[i];
        if (crtg + g <= maxg) {
            int totalg = crtg + g;
            int totalp = crtp + p;
            if (mid + 1 <= n) {
                totalp += a[mid + 1].p;
            }
//            if (mid + 1 <= n) {
//                totalp += min(maxg - totalg, a[mid + 1].g) * a[mid + 1].p / a[mid + 1].g + 1;
//            }
            best = totalp;
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    return best > ans;
}

bool ok1(int i, int crtg, int crtp) {
    int g = crtg;
    int best = crtp;
    for (int j = i + 1; j <= n; j++) {
        if (g + a[j].g <= maxg) {
            best += a[j].p;
            g += a[j].g;
        } else {
            best += a[j].p;
            break;
        }
    }
    return best > ans;
}


void bkt(int i, int crtg, int crtp) {
    if (i == n + 1) {
        ans = max(ans, crtp);
        return;
    }
    if (!ok1(i - 1, crtg, crtp)) {
        return;
    }
    bkt(i + 1, crtg, crtp);
    if (crtg + a[i].g <= maxg) {
        bkt(i + 1, crtg + a[i].g, crtp + a[i].p);
    }
}

signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);
#ifdef LOCAL
    freopen("file.in", "r", stdin);
    freopen("file.out", "w", stdout);
#else
    freopen("rucsac.in", "r", stdin);
    freopen("rucsac.out", "w", stdout);
#endif

    cin >> n >> maxg;
    for (int i = 1; i <= n; i++) {
        cin >> a[i].g >> a[i].p;
    }
    sort(a + 1, a + 1 + n, [&](T x, T y) {
        return x.p * y.g > y.p * x.g;
    });
    for (int i = 1; i <= n; i++) {
        prefp[i] = prefp[i - 1] + a[i].p;
        prefg[i] = prefg[i - 1] + a[i].g;
    }
    int crtg = 0;
    for (int i = 1; i <= n; i++) {
        if (a[i].g + crtg <= maxg) {
            ans += a[i].p;
            crtg += a[i].g;
        }
    }

    bkt(1, 0, 0);
    cout << ans;
}