Cod sursa(job #585935)

Utilizator DraStiKDragos Oprica DraStiK Data 30 aprilie 2011 12:46:36
Problema NumMst Scor 24
Compilator cpp Status done
Runda Algoritmiada 2011, Runda Finală, Clasele 10-12 Marime 2.4 kb
#include <algorithm>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cmath>
using namespace std;

#define MAX 10000005
#define DIM 4005


double bst_0[DIM],bst_1[DIM],lg2[DIM];
int ant_0[DIM],ant_1[DIM],prim[DIM],start[DIM];
bitset <MAX> viz,ok;
int oldN,N,P;

void read ()
{
    int i,j;

    scanf ("%d",&N);

    oldN=N;
    if (!(N&1))
        N=2;

    prim[++P]=2;
    for (i=3; i<=N; i+=2)
        if (!viz[i])
        {
            if (!(N%i))
                N=i;

            prim[++P]=i;
            for (j=3*i; j<=N; j+=(i<<1))
                viz[j]=1;
        }
}

void solve ()
{
    int i,j,val;

    if (!(N%2))
    {
        printf ("%d %d",oldN/2,oldN/2);
        return ;

    }

    if (!(N%3))
    {
        printf ("%d %d",oldN/3,2*oldN/3);
        return ;

    }

    for (i=2; i<=N; ++i)
        lg2[i]=log (i);

    val=0; ok[0]=1; bst_0[0]=0;
    for (i=1; i<=P; ++i)
        for (j=val; j>=0; --j)
            if (ok[j] && j+prim[i]<=N && !ok[j+prim[i]])
            {
                bst_0[j+prim[i]]=bst_0[j]+lg2[prim[i]];
                ant_0[j+prim[i]]=prim[i];
                ok[j+prim[i]]=1;

                val=max (val,j+prim[i]);
            }

    for (i=1; i<=N; ++i)
        if (bst_0[i-1]>bst_0[i])
        {
            start[i]=start[i-1];
            bst_0[i]=bst_0[i-1];
        }
        else
            start[i]=i;

    for (val=start[N]; !bst_0[val]; --val);

    if (val!=N)
        printf ("%d ",(N-val)*(oldN/N));
    for ( ; val; val-=ant_0[val])
        printf ("%d ",ant_0[val]*(oldN/N));

//    bst_0[1]=0; ant_0[1]=1;
//    bst_1[1]=0; ant_1[1]=1;
//    for (i=2; i<=N; ++i)
//    {
//        bst_1[i]=bst_1[i-1]; ant_1[i]=1;
//        for (j=1; j<i; ++j)
//            if (bst_0[i-j]+lg2[j]>bst_1[i])
//            {
//                bst_1[i]=bst_0[i-j]+lg2[j];
//                ant_1[i]=j;
//            }
//        bst_0[i]=bst_1[i]; ant_0[i]=ant_1[i];
//        if (lg2[i]>bst_0[i])
//        {
//            bst_0[i]=lg2[i];
//            ant_0[i]=i;
//        }
//    }
//
//    printf ("%d ",ant_1[N]*(oldN/N));
////    for (val=N-ant_1[N]; val; val-=ant_0[val])
//        printf ("%d ",ant_0[val]*(oldN/N));
}

int main ()
{
    freopen ("nummst.in","r",stdin);
    freopen ("nummst.out","w",stdout);

    read ();
    solve ();

    return 0;
}