Cod sursa(job #18444)

Utilizator astronomyAirinei Adrian astronomy Data 18 februarie 2007 12:13:53
Problema Ghiozdan Scor 60
Compilator c Status done
Runda preONI 2007, Runda 2, Clasele 11-12 Marime 1.48 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];

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];
                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];
            }
        }
        u ^= 1, v ^= 1;
     }

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

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);
}

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

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

    return 0;
}