Cod sursa(job #1410926)

Utilizator CostanMiriamCostan Miriam CostanMiriam Data 31 martie 2015 12:45:35
Problema Ghiozdan Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.12 kb
#include <fstream>
#include <deque>

#define NMAX 201
#define DIM 75001
#define INF (1 << 30)

using namespace std;

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

int n, g;

int f[NMAX];

deque<int> dq;

int dp[2][DIM], T[2][DIM];

int crt;

void solve(int left, int right, int G) {

    crt++;

    if (left == right) {

        if (!f[left])
            return;

         for (int i = 1; i <= G / left; i++) {

                fout << left << "\n";

         }

         return;

    }

    int middle = (left + right) / 2;

    int OLD = 1;
    int NEW = 0;

    int jmax = 0;

    for (int i = 0; i <= G; i++) {

        dp[OLD][i] = ((i / left <= f[left] && i % left == 0)? i / left : INF);

        T[OLD][i] = i;

        if(dp[OLD][i] != INF)
            jmax = i;

    }

    for (int i = left + 1; i <= right; i++) {

        if (!f[i])
            continue;

         for (int j = 0; j <= G; j++)
            dp[NEW][j] = INF;

        for (int mod = 0; mod < i; mod++) {

            dq.clear();

            for (int j = mod; j <= G; j += i) {

                while (!dq.empty() && dp[OLD][dq.back()] + (j - dq.back()) / i > dp[OLD][j])
                    dq.pop_back();

                dq.push_back(j);

                if (((j - dq.front()) / i) > f[i])
                    dq.pop_front();

                dp[NEW][j] = min(INF, dp[OLD][dq.front()] + (j - dq.front()) / i);

                T[NEW][j] = (i <= middle ? j : T[OLD][dq.front()]);

                if (dp[NEW][j] != INF && jmax < j)
                    jmax = j;

            }

        }

        NEW ^= 1;
        OLD ^= 1;

    }

    if (crt == 1) {

        fout << jmax << " " << dp[OLD][jmax] << "\n";

    }

    solve(left, middle, T[OLD][jmax]);
    solve(middle + 1, right, jmax - T[OLD][jmax]);

}

int main() {

    fin >> n >> g;

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

        int x;

        fin >> x;

        f[x]++;

    }

    crt = 0;

    solve(1, 200, g);

    return 0;

}

//Trust me, I'm the Doctor!
//Miriam e tare!