Cod sursa(job #393515)

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

using namespace std;

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

int N,G,gmax;

int CATE[201];

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

int IND[201];

vector<int> V;

int main()
{
    int g;
    
    freopen("ghiozdan.in","r",stdin);
    freopen("ghiozdan.out","w",stdout);
    
    scanf("%d %d",&N,&G);
    
    int sq=(int)sqrt(N);
    
    for(int i=1;i<=N;++i)
    {
       scanf("%d",&g);
       gmax=max(gmax,g); 
       
       if(!CATE[g]) V.PB(g);    
       ++CATE[g];
    }
    
    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<V.size();++i)
    {
       int cur=i%2;
       int prev=!cur;
       
       int cat=V[i];
       
       for(int j=0;j<=G;++j)
          A[j][cur]=inf;
       
       for(int j=0;j<cat;++j)
       {
          int st=0,dr=-1;
               
          for(int k=0;k*cat+j<=G;++k)  
          {
             //scoateri
             
             while((st<=dr) && (k*cat+j-IND[st])>CATE[cat]*cat) ++st;
             
             //inserari   
             
             int val_cur=A[k*cat+j][prev];
             
             if(val_cur!=inf)
             {
                while((st<=dr) && (val_cur<=A[IND[dr]][prev]+(k*cat+j-IND[dr])/cat)) --dr;
             
                ++dr;
                IND[dr]=k*cat+j;  
             }   
             
             if(st<=dr) A[k*cat+j][cur]=A[IND[st]][prev]+(k*cat+j-IND[st])/cat;
             else A[k*cat+j][cur]=inf;
              
          }   
       }     
       /*
       for(int j=0;j<=G;++j)
          printf("%d ",A[j][cur]);
       
       printf("\n");   
       */
    }
    
    int i=G;
    
    while(A[i][(V.size()-1)%2]==inf) --i;
    
    printf("%d %d",i,A[i][(V.size()-1)%2]);
    
    return 0;    
}