Cod sursa(job #2273855)

Utilizator cosminpdrfischer2004 cosminp Data 1 noiembrie 2018 03:09:54
Problema Ghiozdan Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.4 kb
#include <vector>
#include <numeric>
#include <fstream>
using namespace std;
const int INF = 1e9;

vector<int> knapsackCost(int l, int r, vector<int> &c, int s) {
    vector<int> best(s+1, INF); best[0] = 0;
    for (int x = l; x <= r; x++) {
        for (int n = c[x], k = 1; n; n -= k, k = min(2*k, n)) {
            for (int i = s; i >= k*x; i--) {
                best[i] = min(best[i], best[i - k*x] + k);
            }
        }
    }
    return best;
}

void knapsack(int l, int r, vector<int> &c, int s, vector<int> &ans) {
    if (l == r) {
        for (int i = 0; i < min(c[l], s/l); i++) ans.push_back(l);
        return;
    }
    
    int     m = (l + r)/2;
    auto    a = knapsackCost(l,   m, c, s);
    auto    b = knapsackCost(m+1, r, c, s);
    int     t = 0, total = 0;
    for (int i = 0, j = s; i <= s; i++) {
        if (a[i] == INF) continue;
        while (b[j] == INF || i + j > s) j--;
        if (i + j > total) total = i + j, t = i;
    }

    knapsack(l,   m, c, t,   ans);
    knapsack(m+1, r, c, s-t, ans);
}

int main() {
    ifstream    f("ghiozdan.in");
    ofstream    g("ghiozdan.out");
    int         n, s; f >> n >> s;
    vector<int> c(201), ans;
    
    for (int i = 0; i < n; i++) { int x; f >> x; c[x]++; }
    knapsack(1, c.size() - 1, c, s, ans);
    
    g << accumulate(ans.begin(), ans.end(), 0) << " " << ans.size() << "\n";
    for (auto e : ans) g << e << "\n";
    
    return 0;
}