Cod sursa(job #2124718)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 7 februarie 2018 15:21:47
Problema Ghiozdan Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.04 kb
#include <fstream>
#include <vector>
#include <deque>

using namespace std;

ofstream fout ("ghiozdan.out"); ifstream fin ("ghiozdan.in");

const int gmax = 75e4 + 2;
const int nmax = 2e4;
const int valmax = 200;

const int inf = 1 << 30;

int ind;
int f[valmax + 1];
int dp[ 2 ][gmax + 1];
pair<int, int> r[ 2 ][gmax + 1];

deque<pair<int, int>> d;
vector< int > sol;

void solve (int x, int y, int s) {
    if (x > y)
        return ;

    for (int i = 0; i <= s; ++ i)
        dp[ 0 ][ i ] = inf;
    dp[ 0 ][ 0 ] = 0;

    ind = 1;
    int mij = (x + y) / 2;

    for (int i = 1; i <= y - x + 1; ++ i, ind = 1 - ind) {
        int nr = i + x - 1;

        for (int rest = 0; rest < nr; ++ rest) {
            d.clear();
            for (int j = rest; j <= s; j += nr) {
                int vl = dp[1 - ind][ j ] - j / nr;

                while (!d.empty() && d.back().second >= vl) {
                    d.pop_back();
                }

                d.push_back(make_pair(j, vl));

                if (d.front().first < j - nr * f[ nr ]) {
                    d.pop_front();
                }

                dp[ ind ][ j ] = min(inf, d.front().second + j / nr);
                r[ ind ][ j ] = r[1 - ind][ d.front().first ];

                if (nr == mij) {
                    r[ ind ][ j ] = make_pair((j - d.front().first) / nr, j);
                }
            }
        }
    }

    int sum = s;
    ind = 1 - ind;
    while (sum >= 0 && dp[ ind ][ sum ] == inf) {
        -- sum;
    }

    for (int j = 0; j < r[ ind ][ sum ].first; ++ j)
        sol.push_back( mij );

    int saux = r[ ind ][ sum ].second;
    solve(x, mij - 1, saux - mij * r[ ind ][ sum ].first);
    solve(mij + 1, y, sum - saux);
}

int main () {
    int n, k;
    fin >> n >> k;

    for (int i = 1; i <= n; ++ i) {
        int x;
        fin >> x;
        ++ f[ x ];
    }

    solve(1, valmax, k);

    int ans = 0;
    for (auto i : sol)
        ans += i;

    fout << ans << " " << (int)sol.size() << "\n";
    for (auto i : sol)
        fout << i << "\n";

    fout.close();
    return 0;
}