Cod sursa(job #18086)

Utilizator dominoMircea Pasoi domino Data 18 februarie 2007 02:56:59
Problema Ghiozdan Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.21 kb
#include <stdio.h>

#define INF 0x3f3f3f3f

int N, G, cnt[256], sol[20000], ns;
int A[256][1024], T[256][1024];

void trace(int n, int k)
{
    int i;

    if (!n) return;
    trace(n-1, k-T[n][k]*n);
    for (i = 0; i < T[n][k]; i++)
        sol[ns++] = n;
}

int main(void)
{
    int i, g, x, j, k;

    freopen("ghiozdan.in", "r", stdin);
    freopen("ghiozdan.out", "w", stdout);

    scanf("%d %d", &N, &G);
    for (i = 0; i < N; i++)
    {
        scanf("%d", &x);
        cnt[x]++;
    }

    for (i = 200, g = G; i > 0 && g > 1000; i--)
        for (; g >= i && cnt[i]; cnt[i]--, g -= i)
            sol[ns++] = i; 

    for (i = 1; i <= g; i++) A[0][i] = INF;
    for (i = 1; i <= 200; i++)
        for (j = 0; j <= g; j++)
        {
            A[i][j] = A[i-1][j];
            for (k = 1; k <= cnt[i] && i*k <= j; k++)
                if (A[i][j] > A[i-1][j-i*k]+k)
                {
                    A[i][j] = A[i-1][j-i*k]+k;
                    T[i][j] = k;
                }
        }

    for (i = g; i >= 0 && A[200][i] == INF; i--);
    trace(200, i);

    printf("%d %d\n", G-g, ns);
    for (i = 0; i < ns; i++)
        printf("%d\n", sol[i]);

    return 0;
}