Cod sursa(job #393608)

Utilizator perticas_catalinperticas catalin perticas_catalin Data 9 februarie 2010 18:42:57
Problema Ghiozdan Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.19 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];

int ob[NM];

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

int main()
{
    int g;
    
    int A[GM][2];
    
    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;
       B[i][0]=inf;
    }
    
    for(int i=1;i<=N;++i)
    {
       int cur=i%2;
       int prev=!cur;
       
       for(int j=0;j<=G;++j)
          P[j]=A[j][prev];
       
       PD(V[i]);
       
       for(int j=0;j<=G;++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;
    
    if(N%sq==0) --dim;
    
    int indi=N;
    
    int d=0;
    
    for(int l=dim;l>=0;--l)
    {
        for(int j=0;j<=G;++j)
           R[j][0][0]=B[j][l];
        
        for(int i=l*sq+1,ii=1;i<=min((l+1)*sq,N);++i,++ii)
        {
           for(int j=0;j<=G;++j)
              P[j]=R[j][ii-1][0];
           
           PD(V[i]);
           
           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)
              ob[++d]=V[indi];
            
           poz-=(R[poz][indii][1]*V[indi]); 
              
           --indi;
           --indii;
        }
    }
    
    int sum=0;
    
    for(int i=1;i<=d;++i)
    {
       printf("%d\n",ob[i]);
       sum+=ob[i];
    }     
    
    return 0;
}