//gutui
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
/*int min(int a, int b){
if(a>b) return a;
else return b;
}*/
int compare (const void * a, const void * b)
{
return -( *(int*)a - *(int*)b );
}
int compare1 (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int main(){
int n,h,u,i,j,niv=0,a,flag,max=-5,c=0,sum=0,l,k,z; // c = nr de gutui din solutie; sum= suma maselor gutuilor
int* g[2];
int* p[2];
int **m;
int* sol;
FILE *f;
f=fopen("gutui.in", "r");
if(!f) return -1;
fscanf(f,"%i",&n);
fscanf(f,"%i",&h);
fscanf(f,"%i",&u);
g[0]=(int*)malloc(n*sizeof(int));
g[1]=(int*)malloc(n*sizeof(int));
p[0]=(int*)malloc(n*sizeof(int));
p[1]=(int*)malloc(n*sizeof(int));
for(i=0;i<n;i++){
fscanf(f,"%i",&g[0][i]);
fscanf(f,"%i",&g[1][i]);
p[0][i]=-1;
p[1][i]=0;
}
fclose(f);
for(i=0;i<n;i++){
a=(h-g[0][i])/u + 1;
flag=0;
for(j=0;j<niv;j++){
if (a==p[0][j]) {
flag=1;
p[1][j]++;
}
else continue;
}
if (flag==0) {p[0][niv]=a; p[1][niv]=1; niv++;}
}
for(i=0;i<niv;i++){
// printf("nivel: %i nr gutui: %i\n", p[0][i],p[1][i]);
if (p[1][i]>max) max=p[1][i];
}
m=(int**)malloc(niv*sizeof(int*));
for(i=0;i<niv;i++)
m[i]=(int*)malloc((max+2)*sizeof(int));
for(i=0;i<niv;i++){
m[i][0]=p[0][i];
m[i][1]=0;
for(j=2;j<(max+2);j++){
m[i][j]=-1;
}
}
for(i=0;i<n;i++){
a=(h-g[0][i])/u + 1;
for(j=0;j<niv;j++){
if(m[j][0]==a) break;
}
a=m[j][1]+2;
m[j][a]= g[1][i];
m[j][1]++;
}
//alocare spatiu vector solutie si intializare cu 0;
sol=(int*)malloc(p[0][niv-1]*sizeof(int)); // sau max
for(i=0;i<p[0][niv-1];i++) sol[i]=0;
//sortez matricea m descrescator
for(i=0;i<niv;i++)
qsort (m[i]+2, m[i][1], sizeof(int), compare);
//afisare matricea m
/*for(i=0;i<niv;i++){
printf("\n");
for(j=0;j<max+2;j++){
printf("%i ", m[i][j]);
}
}*/
for(i=0;i<niv;i++){
// r=min(m[i][0],m[i][1]); // ??
if(m[i][0]-c>=m[i][1]){
for(j=2;m[i][j]!=-1;j++){
sol[c]=m[i][j];
c++;
}
qsort(sol,c,sizeof(int),compare1) ;
/*printf("[%i]: ", m[i][0]);
for(z=0;z<p[0][niv-1];z++) printf("%i ", sol[z]);
printf("\n"); */
}
else{
for(j=2;j<m[i][0]-c+2;j++){
sol[c]= m[i][j];
c++;
}
qsort(sol,c,sizeof(int),compare1) ;
for(k=j;k<m[i][0] && m[i][k]!=-1;k++){ //??
//verific daca vectorul de solutii partiale contine o gutuie mai usoara
for(l=c-1;l>=0;l--){
if (sol[l]<m[i][k]) {sol[l]=m[i][k]; break;}
}
if(l==0) break;
}
/*printf("[%i]: ", m[i][0]);
for(z=0;z<p[0][niv-1];z++) printf("%i ", sol[z]);
printf("\n");*/
}
}
for(i=0;i<p[0][niv-1];i++)
sum=sum+sol[i];
printf("suma:%i\n", sum);
//afisare nivele din p si m
//for(i=0;i<n;i++) printf("%i ", p[i][0]);
printf("\n");
//for(i=0;i<niv;i++) printf("%i ", m[i][0]);
//printf("col: %i, linii: %i", niv,max);
getch();
return 0;
}