#include <stdio.h>
#include <stdlib.h>
typedef struct {
unsigned long h;
unsigned long g;
} gutuie;
typedef struct {
unsigned int i;
unsigned int nv;
} nivel;
gutuie vg[100000];
unsigned long N, H, U;
nivel niv[100000];
int nivc = 0;
gutuie vsol[100000];
void citeste()
{
FILE *f = fopen("gutui.in", "rt");
int i;
if ( f == NULL )
return;
fscanf(f, "%ld%ld%ld", &N, &H, &U);
for (i = 0; i < N; i++) {
fscanf(f, "%ld%ld", &vg[i].h, &vg[i].g);
}
fclose(f);
}
int ncx(gutuie gut)
{
return gut.g / (( H - gut.h ) / U + 1);
}
int pas(gutuie gut)
{
return (H - gut.h) / U;
}
int comp1(const void *s1, const void *s2)
{
return ((gutuie*)s2)->g - ((gutuie*)s1)->g;
//return (float) ((gutuie*)s2)->g / ((gutuie*)s2)->h - (float) ((gutuie*)s1)->g / ((gutuie*)s1)->h;
}
int comp2(const void *s1, const void *s2)
{
//return ((gutuie*)s2)->h - ((gutuie*)s1)->h;
return (float) ((gutuie*)s2)->g / ((gutuie*)s2)->h - (float) ((gutuie*)s1)->g / ((gutuie*)s1)->h;
}
int comp3(const void *s1, const void *s2)
{
return ( H - ((gutuie*)s1)->h ) / U - ( H - ((gutuie*)s2)->h ) / U;
//return (float) ((gutuie*)s2)->g / ((gutuie*)s2)->h - (float) ((gutuie*)s1)->g / ((gutuie*)s1)->h;
}
int comp4(const void *s1, const void *s2)
{
return ((gutuie*)s2)->h - ((gutuie*)s1)->h;
}
int comp5(const void *s1, const void *s2)
{
return ((gutuie*)s2)->g / (( H - ((gutuie*)s2)->h ) / U+1) - ((gutuie*)s1)->g / (( H - ((gutuie*)s1)->h ) / U+1);
//return ((gutuie*)s2)->g / 2 ;//( H - ((gutuie*)s2)->h ) / U ;
// ((gutuie*)s1)->g / ( H - ((gutuie*)s1)->h ) / U;
}
int comp6(const void *s1, const void *s2)
{
return *(int*)s2 - *(int*)s1;
}
int main(int argc, char **argv)
{
unsigned long maxg, sol;
unsigned long i, j, ncmax, ncmin, im, nci, alese, mnext, sg;
citeste();
qsort(vg, N, sizeof(gutuie), comp3);
i = 0;
nci = 0;
while (i < N) {
while ( pas(vg[i]) != nci )
nci++;
if ( pas(vg[i]) == nci ) {
niv[nivc].nv = pas(vg[i]);
niv[nivc].i = i;
nivc++;
}
while ( pas(vg[i]) == nci )
i++;
nci++;
//i++;
}
ncmax = pas(vg[N-1]);
sol = 0;
for (i = 0; i < N; i++)
printf("%ld %ld -> %ld\n", vg[i].h, vg[i].g, pas(vg[i]));
printf("\n");
for (i = 0; i < nivc; i++)
printf("%ld -> %ld\n", niv[i].i, niv[i].nv);
/*
alese = 0;
sol = 0;
for (i = 0; i < N; i++) {
if ( vg[i].h + alese * U > H )
break;
sol += vg[i].g;
alese++;
}
ncmax = sol;
qsort(vg, N, sizeof(gutuie), comp4);
alese = 0;
sol = 0;
for (i = 0; i < N; i++) {
if ( vg[i].h + alese * U > H )
break;
sol += vg[i].g;
alese++;
}
if ( sol > ncmax )
ncmax = sol;
*/
/*
nci = N;
alese = 0;
ncmin = 1 << 32 - 1;
mnext = 0;
ncmin = 1;
while ( nci > 0 ) {
printf("caut %d\n", ncmin);
// caut gutui cu nc egal cu ncmin si aleg pe cele cu g max
maxg = 0;
im = -1;
for (i = 0; i < N; i++)
if ( !vg[i].used && vg[i].g > maxg && (H - vg[i].h) / U + 1 == ncmin ) {
maxg = vg[i].g;
im = i;
}
if ( im == -1 )
break;
vg[im].used = 1;
alese++;
for (i = 0; i < N; i++)
if ( !vg[i].used && vg[i].g > maxg && (H - vg[i].h) / U + 1 > ncmin && ncmax < (H - vg[i].h) / U + alese + 1 ) {
printf("am pierdut %d\n", vg[i].g);
vg[im].used = 0;
ncmin++;
alese--;
break;
}
if ( vg[im].used ) {
printf("\tam ales %d \n", vg[im].g);
sol += vg[im].g;
}
nci--;
}
*/
/*
sol = 0;
i = 0;
sg = 0;
for ( im = 1; im <= ncmax; im++ ) {
maxg = 0;
nci = im;
while ( i < N && (H - vg[i].h) / U + 1 == nci ) {
if ( vg[i].g > maxg )
maxg = vg[i].g;
i++;
}
if ( maxg == 0 )
continue;
printf("aleg %ld la %ld\n", maxg, nci);
sg = sg + maxg;
printf("\n");
}
sol = sg;*/
/*
sol = vg[0].g;
sg = vg[0].g / ((H - vg[0].h) / U+1);
i = 1;
printf("aleg %d\n", vg[0].g);
while ( i < N ) {
if ( vg[i].g / ((H - vg[i].h) / U +1)< sg ) {
sg = vg[i].g / ((H - vg[i].h) / U+1);
sol = sol + vg[i].g;
printf("aleg %d\n", vg[i].g);
}
i++;
}*/
/*
sol = 0;
alese = 0;
for (i = 0; i < N; i++) {
if ( vg[i].h + U * alese <= H ) {
sol += vg[i].g;
printf("aleg %d\n", vg[i].g);
alese++;
for (j = i + 1; j < N; j++)
if ( vg[j].g > vg[i].g && vg[j].h + U * alese > H ) {
sol -= vg[i].g;
printf("elimin %d din cauza %d\n", vg[i].g, vg[j].g);
alese--;
break;
}
}
}*/
/*
sol = 0;
alese = 0;
for (i = 0; i < N; i++) {
if ( vg[i].h + U * alese <= H ) {
sol += vg[i].g;
alese++;
}
}*/
int o;
unsigned long smax = 0;
for (o = 0; o < N; o++) {
sol = 0;
nci = niv[0].nv;
alese = 0;
maxg = 0;
i = 0;
int k;
im = 0;
while ( im < nivc ) {
nci = niv[im].nv;
if ( nci == pas(vg[N-1]) ) {
j = N;
} else {
j = niv[im+1].i;
}
ncmax = nci + 1 - alese;
printf("la nivelul %d iau cel mult %d gutui\n", nci, ncmax);
sg = 0;
if ( j - i < ncmax )
ncmax = j - i;
while ( i < j ) {
printf("\tsol %d\n", vg[i].g );
if ( i == o )
i++;
vsol[sg].g = vg[i].g;
vsol[sg++].h = vg[i++].h;
}
qsort(vsol, sg, sizeof(gutuie), comp1);
sg = 0;
printf("max = %d\n", ncmax);
while ( sg < ncmax ) {
j = N - 1;
while ( j > i ) {
if ( vg[j].g > vsol[sg].g && vg[j].h + ( alese + j - i )*U > H )
break;
j--;
}
printf("i = %d, alese = %d, j = %d, h = %d\n", i, alese, j, vg[j].h + (alese + j - i )*U);
if ( vsol[sg].h + alese * U <= H && j == i ||
vsol[sg].h + alese * U <= H && nci == pas(vg[N-1]) ) {
printf("\tam ales %d\n", vsol[sg].g);
sol += vsol[sg++].g;
alese++;
} else {
printf("\tnu aleg %d din cazula la %d\n", vsol[sg].g, vg[j].g);
sg++;
}
}
im++;
}
if ( sol > smax )
smax = sol;
printf("SOL: %ld\n", sol);
}
FILE *f = fopen("gutui.out", "wt");
fprintf(f, "%ld\n", smax);
fclose(f);
return 0;
}