Cod sursa(job #1348555)

Utilizator assa98Andrei Stanciu assa98 Data 19 februarie 2015 19:17:41
Problema Ghiozdan Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.03 kb
#include <fstream>
#include <deque>
#include <algorithm>
using namespace std;

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

const int MAX_G = 75100;
const int MAX_N = 20100;
const int MAX_VAL = 210;
const int INF = MAX_N;

int v[MAX_VAL];
int d[2][MAX_G];
int dad[2][MAX_G];
int p[2][MAX_G];

void dinamic(int st, int dr, int g) {
    if(!g) {
        return;
    }

    if(st == dr) {
        for(int i = 1; i * st <= g && i <= v[st]; i++) {
            fout << st << '\n';
        }
        return;
    }

    for(int i = 0; i <= g; i++) {
        d[0][i] = d[1][i] = INF;
    }

    d[0][0] = 0;

    int mij = (st + dr) / 2;

    for(int i = st; i <= dr; i++) {
        for(int r = 0; r < i; r++) {
            deque<int> Q;
            for(int j = r; j <= g; j += i) {
                d[1][j] = d[0][j];
                p[1][j] = (i <= mij ? j : p[0][j]);
                if(!Q.empty()) {
                    int c = d[0][Q.front()] + (j - Q.front()) / i;
                    if(c < d[1][j]) {
                        d[1][j] = c;
                        p[1][j] = (i <= mij ? j : p[0][Q.front()]);
                    }
                }
                while(!Q.empty() && d[0][j] <= d[0][Q.back()]) {
                    Q.pop_back();
                }
                if(d[0][j] != INF) {
                    Q.push_back(j);
                }
                while(!Q.empty() && (j - Q.front()) / i >= v[i]) {
                    Q.pop_front();
                }
            }
        }

        for(int j = 0; j <= g; j++) {
            d[0][j] = d[1][j];
            d[1][j] = INF;
            p[0][j] = p[1][j];
            p[1][j] = 0;
        }
    }

    int ng = 0;
    for(ng = g; d[0][ng] == INF; ng--);

    if(st == 1 && dr == 200) {
        fout << ng << ' ' << d[0][ng] << '\n';
    }

    ng = p[0][ng];
    dinamic(st, mij, ng);
    dinamic(mij + 1, dr, g - ng);
}


int main() {
    int n, g;
    fin >> n >> g;
    for(int i=1;i<=n;i++) {
        int a;
        fin >> a;
        v[a]++;
    }

    dinamic(1, 200, g);


    return 0;
}