Cod sursa(job #1926095)

Utilizator akaprosAna Kapros akapros Data 13 martie 2017 22:56:06
Problema Ghiozdan Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.27 kb
#include <bits/stdc++.h>
#define maxN 20001
#define maxG 75001
#define maxW 201
using namespace std;

FILE *fin = freopen("ghiozdan.in", "r", stdin);
FILE *fout = freopen("ghiozdan.out", "w", stdout);

/* ------------- */
int n, g;
/* ------------- */
struct Dp
{
    int prv, nro, obj;
} dp[maxW + 1][maxG + 1];
int t, frq[maxW + 1];
deque < int > dq;
/* ------------- */
int gmax;

void read()
{
    scanf("%d %d", &n, &g);
    for (int i = 1; i <= n; ++ i)
    {
        int w;
        scanf("%d", &w);
        ++ frq[w];
    }
}

void Push_dq(int i, int t, int j)
{
    while (!dq.empty() && dp[t - 1][dq.back()].nro - dq.back() / i > dp[t - 1][j].nro - j / i)
        dq.pop_back();
    dq.push_back(j);
}

void init()
{
    for (int i = 1; i < maxG; ++ i)
        dp[0][i] = {0, maxN, 0};
}

void solve()
{
    init();
    dp[0][0] = {0, 0, 0};
    for (int i = maxW - 1; i >= 1; -- i)
        if (frq[i])
        {
            ++ t;
            dq.clear();
            for (int j = 1; j <= g; ++ j)
                dp[t][j].nro = maxN;
            for (int st = 0; st < i; ++ st)
            {
                dq.clear();
                Push_dq(i, t, st);
                for (int j = st + i; j <= g; j += i)
                {

                    Push_dq(i, t, j);
                    //if (dp[t][j].nro > dp[t][dq.front()].nro + (j - dq.front()) / i)

                    dp[t][j].prv = dq.front();
                    if (dp[t - 1][dq.front()].nro != maxN)
                        dp[t][j].nro = dp[t - 1][dq.front()].nro + j / i - dq.front() / i;
                    else
                        dp[t][j].nro = maxN;
                    dp[t][j].obj = i;

                    if (dq.front() == j - frq[i] * i)
                        dq.pop_front();
                    if (j > gmax && dp[t][j].nro != maxN)
                        gmax = j;
                }
            }
        }
}

void write()
{
    printf("%d %d\n", gmax, dp[t][gmax].nro);
    int G = gmax;
    while (G)
    {
        for (int i = 1; i <= (G - dp[t][G].prv) / dp[t][G].obj; ++ i)
            printf("%d\n", dp[t][G].obj);
        G = dp[t][G].prv;
        -- t;
    }
}

int main()
{
    read();
    solve();
    write();
    return 0;
}