Cod sursa(job #393617)

Utilizator perticas_catalinperticas catalin perticas_catalin Data 9 februarie 2010 18:57:14
Problema Ghiozdan Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.16 kb
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>

using namespace std;

#define PB push_back
#define GM 75005
#define NM 20005
#define inf 2000000000

int N,G,gmax;

int P[GM],D[GM],E[GM];

int CATE[205];

int B[GM][16],R[GM][16][2],A[GM][2];

inline void PD(int cat,int pu)
{
     int IND[1005];  
       
     for(int j=0;j<cat;++j)
     {
        int st=0,dr=-1;
             
        for(int k=0;;++k)  
        {
           int cp=k*cat+j;  
           
           if(cp>pu) break;
             
           while((st<=dr) && (cp-IND[st])>CATE[cat]*cat) ++st;
             
           int vc=P[cp];
             
           if(vc!=inf)
           {
              while((st<=dr) && (vc<=P[IND[dr]]+(cp-IND[dr])/cat)) --dr;
            
              ++dr;
              IND[dr]=cp;  
           }   
             
           if(st<=dr) 
           {
              D[cp]=P[IND[st]]+(cp-IND[st])/cat;
              E[cp]=(cp-IND[st])/cat;
           }   
           else D[cp]=inf;
              
       }   
    }       
}

int main()
{
    int g;
    
    vector<int> V;
    
    freopen("ghiozdan.in","r",stdin);
    freopen("ghiozdan.out","w",stdout);
    
    scanf("%d %d",&N,&G);
    
    for(int i=1;i<=N;++i)
    {
       scanf("%d",&g);
       gmax=max(gmax,g); 
       
       if(!CATE[g]) V.PB(g);    
       ++CATE[g];
    }
    
    N=V.size();
    
    int sq=(int)sqrt(N);
    
    V.PB(0);
    
    sort(V.begin(),V.end());
    
    int dim=0;
    
    for(int i=1;i<=G;++i)
    {
       A[i][0]=inf;
       A[i][1]=inf;
       B[i][0]=inf;
    }
    
    int sum=0;
    
    for(int i=1;i<=N;++i)
    {
       sum+=V[i]*CATE[V[i]];     
            
       int cur=i%2;
       int prev=!cur;
       
       for(int j=0;j<=sum;++j)
          P[j]=A[j][prev];
       
       PD(V[i],sum);
       
       for(int j=0;j<=sum;++j)
          A[j][cur]=D[j];  
       
       if(i%sq==0)
       {
          ++dim;
          for(int j=0;j<=G;++j) B[j][dim]=A[j][cur];        
       }   
    }
    
    int ind=G;
    
    while(A[ind][N%2]==inf) --ind;
    
    int ans=A[ind][N%2];
    
    printf("%d %d\n",ind,ans);
    
    int poz=ind;
    int indi=N;
    
    if(N%sq==0) --dim;
    
    for(int l=dim;l>=0;--l)
    {
        for(int j=0;j<=G;++j)
           R[j][0][0]=B[j][l];
        
        int lim=min((l+1)*sq,N);
        
        for(int i=l*sq+1,ii=1;i<=lim;++i,++ii)
        {
           for(int j=0;j<=G;++j)
              P[j]=R[j][ii-1][0];
           
           PD(V[i],G);
           
           for(int j=0;j<=G;++j)
           {
              R[j][ii][0]=D[j];
              R[j][ii][1]=E[j];
           }        
        }     
        
        int indii=indi%sq;
        
        if(indii==0) indii=sq;   
        
        while(indii)
        {
           for(int j=1;j<=R[poz][indii][1];++j)
              printf("%d\n",V[indi]);
            
           poz-=(R[poz][indii][1]*V[indi]); 
              
           --indi;
           --indii;
        }
    }
    
    return 0;
}