Cod sursa(job #516966)

Utilizator GavrilaVladGavrila Vlad GavrilaVlad Data 27 decembrie 2010 12:42:17
Problema Ghiozdan Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 1.58 kb
#include <stdio.h>
#include <algorithm>
#include <string.h>

using namespace std;

#define maxn 75010
#define maxw 210
#define inf 2000000000

int n, gmax, i, poz, j, k, w, sol, v[maxw];
int d[2][maxn], p[2][maxn], dq[maxn];

void dinamica(int left, int right, int g, int tip)
{
    if(left==right)
    {
        for(int i=1; i<=g/left; ++i)
            printf("%d\n", left);
        return;
    }
    int med=(left+right)/2;
    d[0][0]=0;
    for(int i=1; i<=g; ++i)
        d[0][i]=inf;
    poz=0;
    for(int i=left; i<=right; ++i)
    {
        for(int j=0; j<i; ++j)
        {
            int l=1, r=0;
            for(int k=j, cnt=0; k<=g; k+=i, ++cnt)
            {
                if(dq[l]<k-v[i]*i && l<=r)
                    ++l;
                while(d[poz][k]<d[poz][dq[r]]+cnt-dq[r]/i && l<=r)
                    --r;
                dq[++r]=k;
                d[poz^1][k]=d[poz][dq[l]]+cnt-dq[l]/i;
                if(i<=med)
                    p[poz^1][k]=k;
                else
                    p[poz^1][k]=p[poz][dq[l]];
            }
        }
        poz^=1;
    }
    if(tip==1)
    {
        int sol=g;
        while(d[poz][sol]==inf)
            --sol;
        printf("%d %d\n", sol, d[poz][sol]);
        g=sol;
    }
    int g1=p[poz][g];
    dinamica(left, med, g1, 0);
    dinamica(med+1, right, g-g1, 0);
}

int main()
{
    freopen("ghiozdan.in", "r", stdin);
    freopen("ghiozdan.out", "w", stdout);
    scanf("%d%d", &n, &gmax);
    for(int i=1; i<=n; ++i)
    {
        scanf("%d", &k);
        v[k]++;
        w=max(w, k);
    }
    dinamica(1, w, gmax, 1);
    return 0;
}