#include<stdlib.h>
#include<stdio.h>
//int max[];
int N=0, H=0, U=1, nr=0, i, ii, j, k=0, aux=0, r, t, a=0, b=0, suma=0, **max, *diag, *ord;
FILE *f, *g;
int compare_int (const void *Y, const void *Z)
{
int y = *((int *)Y);
int z = *((int *)Z);
if (y > z)
{
return -1;
}
else
{
if (y < z)
{
return 1;
}
else
{
return 0;
}
}
}
int main()
{
f = fopen("gutui.in","r");
if(!f) {printf("eroare f"); return 1;}
g = fopen("gutui.out","w");
if(!f) {printf("eroare g"); return 2;}
fscanf(f,"%i", &N);
fscanf(f,"%i", &H);
fscanf(f,"%i", &U);
nr = H/U; //nr=numarul de nivele si totodata numarul maxim de gutui ce pot fi culese din pom
max = calloc ((N+nr+2),sizeof(int*));
ord = calloc ((N+nr+2),sizeof(int*));
for(i=0;i<=nr+1;i++) { max[i] = calloc (N+nr+1,sizeof(int));
}
//citirea datelor
int max_lev = 0;
for(i=0;i<N;i++)
{
fscanf(f,"%i", &a); //a este inaltime initiala
fscanf(f,"%i", &b); //b este greutatea
if(a<=H)
{
j= nr - (a)/U; //j indica ordinea de evaluare, adica nivelul pe care se va gasi gutuia citita
max_lev = (j > max_lev) ? j : max_lev;
ord[j]++; r = ord[j]; //ord[j]= numarul de gutui de pe linia j in matricea max
max[j][r-1]=b; //retin greutatea
}
}
for(i=0; i<=max_lev; i++) qsort((void *)(max[i]), N, sizeof(int), compare_int); //sortez fiecare linie descrescator dupa greutate; O(nr*logN)
diag = calloc (N+nr+1,sizeof(int));
int min = 0;
int pos_min = 0;
k=0;
int step=0;
for(i=0; i<=max_lev; i++)
{ for(j=0; j<=i-1; j++) if(max[i][j] > 0) //de pe nivelul i pot culege maximum i gutui
{
printf("prelucrez %i: diag = ( ", max[i][j]);
for(step=0;step<k;step++) printf("%i ", diag[step]);
printf(")\n");
if(k<=max_lev) { diag[k] = max[i][j];
if(diag[k]<=min) {
min=diag[k];
pos_min = k;
}
k++;
}
else
//if(max[i][j] > 0) {
if(max[i][j] > min) {
diag[pos_min] = max[i][j]; min = N;
for(step=0;step<k;step++) if(diag[step]<=min) {
min=diag[step];
pos_min = step;
}
}
//else if(k<nr) { diag[k++] = max[i][j]; min = max[i][j]; pos_min = k-1; }
//} //pun in diag doar gutuile, nu si locurile libere
else j = i-1; //altfel intrerup for-ul interior pentru i-ul curent
}
}
#if 0
for(i = 0; i <= N+nr; i++) diag[i]=0;
k=0;
for(i=1; i<=nr; i++)
{ for(j=0; j<=i-1; j++) //de pe nivelul i pot culege maximum i gutui
{
if(max[i][j] > 0) { diag[k] = max[i][j]; k++; } //pun in diag doar gutuile, nu si locurile libere
else j = i-1; //altfel intrerup for-ul interior pentru i-ul curent
}
}
qsort((void *)diag, N+nr+1, sizeof(int), compare_int); //sortez descrescator dupa greutate gutuile din vectorul diag
#endif
for(j=0; j<nr; j++) suma+=diag[j]; //pot lua maximum nr gutui (daca in diag am pus mai putin de nr gutui, restul elementelor vor fi 0 si nu vor influenta suma
fprintf(g,"%i", suma);
free (max);
fclose(f);
fclose(g);
return 0;
}