Cod sursa(job #18516)

Utilizator astronomyAirinei Adrian astronomy Data 18 februarie 2007 12:31:00
Problema Ghiozdan Scor 76
Compilator c Status done
Runda preONI 2007, Runda 2, Clasele 11-12 Marime 2.01 kb
#include <stdio.h>

#define INF (1 << 30)
#define MAXG 76000
#define MAXVAL 256

int N, G, Gmax, Nmin, V[MAXVAL], Min[2][MAXG];

int Q[MAXG], Pos[MAXG];

short int R[201][30002];

void solve(void)
{
    int i, t, k, g, p, u = 0, v = 1, inc, sf;

    for(g = 1; g <= G; g++)
        Min[u][g] = INF;
    Min[u][0] = 0;

    for(i = 1; i <= 200; i++)
     if(V[i])
     {
        for(k = 0; k < i; k++)
        {
            Q[inc = sf = 0] = Min[u][k], Pos[0] = 0;
            for(t = 0, p = k; p <= G; p += i, t++)
            {
                Min[v][p] = Min[u][p];

                if(p <= 30000)
                    R[i][p] = 0;
                    
                for(; Min[u][p] <= Q[sf]+(t-Pos[sf]) && sf >= inc; sf--) ;

                Q[++sf] = Min[u][p], Pos[sf] = t;

                if(t-Pos[inc] > V[i])
                    inc++;
                    
                if(Min[v][p] > Q[inc]+t-Pos[inc])
                {
                    Min[v][p] = Q[inc]+t-Pos[inc];
                    if(p <= 30000)
                        R[i][p] = t-Pos[inc];
                }
            }
        }
        u ^= 1, v ^= 1;
     }

    for(g = G; g >= 0; g--)
     if(Min[u][g] < INF)
     {
        Gmax = g, Nmin = Min[u][g];
        break ;
     }
}

void rec(int n, int g)
{
    int i;
    
    if(g == 0)
        return ;

    if(V[n] == 0)
        rec(n-1, g);
    else
    {
        for(i = 1; i <= R[n][g]; i++)
            printf("%d\n", n);
        rec(n-1, g-R[n][g]*n);
    }
}

void read_data(void)
{
    int i, v;

    scanf("%d %d\n", &N, &G);

    for(i = 1; i <= N; i++)
        scanf("%d\n", &v), V[v]++;
}

void write_data(void)
{
    printf("%d %d\n", Gmax, Nmin);
    if(Gmax <= 30000)
        rec(200, Gmax);
}

int main(void)
{
    freopen("ghiozdan.in", "rt", stdin);
    freopen("ghiozdan.out", "wt", stdout);

    read_data();
    solve();
    write_data();

    return 0;
}