Cod sursa(job #882078)

Utilizator mihai995mihai995 mihai995 Data 18 februarie 2013 21:10:25
Problema Ghiozdan Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.6 kb
#include <fstream>
#include <cstring>
#include <deque>
using namespace std;

const int N = 75001, M = 201, inf = 0x3f3f3f3f;

int v[N], a[M], val[N], n, G;
deque<int> Q;

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

void read(){
    int x;

    in >> n >> G;

    for (int i = 1 ; i <= n ; i++){
        in >> x;

        ++a[x];
    }
}

void add(int x){
    if (x <= 0)
        return;

    while (!Q.empty() && val[Q.back()] >= val[x])
        Q.pop_back();

    Q.push_back(x);
}

void remove(int x){
    if (!Q.empty() && Q.front() == x)
        Q.pop_front();

}

void solve(int d0, int step, int nr){
    int n = 0;

    for (int j = d0 ; j <= G ; j += step)
        val[++n] = v[j] - n;

    Q.clear();

    for (int i = n, j = n + nr ; j ; i--, j--){
        remove(j + 1);
        add(i);

        if (!Q.empty() && j <= n)
            val[j] = min(val[j], val[Q.front()]);
    }

    for (int i = 1, j = d0 ; j <= G ; j += step, i++)
        v[j] = i + val[i];
}

void compute(){
    memset(v, inf, sizeof(v));
    v[0] = 0;

    for (int i = 1 ; i < M ; i++){
        if (!a[i])
            continue;

        for (int j = 0 ; j < i ; j++)
            solve(j, i, a[i]);
    }

    while (v[G] == inf)
        G--;
}

void write(){
    out << G << " " << v[G] << "\n";

    for (int i = G, j = 1 ; i ; ){
        while (!a[j] || v[i - j] + 1 != v[i])
            j++;

        --a[j];
        i -= j;

        out << j << "\n";
    }
}

int main(){
    read();

    compute();

    write();

    return 0;
}