#include <stdio.h>
#include <stdlib.h>
#define infile "gutui.in"
#define outfile "gutui.out"
int NMAX = 100000;
int N, H, U;
typedef struct{
int height;
int weight;
} fruit;
int compare_fruit(const void* A, const void* B)
{
const fruit *a = A;
const fruit *b = B;
if (a->weight < b->weight)
return -1;
if (a->weight > b->weight)
return 1;
if (a->height < b->height)
return -1;
if (a->height > b->height)
return 1;
return 0;
}
int sum(fruit *fr)
{
int i, s = 0;
for (i = 0; i < N; i++)
s += fr[i].weight;
return s;
}
int min_height(fruit *fr)
{
int i, m = H+1;
for (i = 0; i < N; i++)
if (fr[i].height < m)
m = fr[i].height;
return m;
}
int solve1(fruit* fr)
{
/* Se poate rezolva mult mai eficient folosind maxheap */
if (U == 0)
return sum(fr);
int i, count = 0;
int current_height = 0, current_weight = 0;
int ceil = (H - min_height(fr))/U +1;
qsort(fr, N, sizeof(fruit), compare_fruit);
/* While the current height is smaller than the maximum height and
* the number of picked fruits is smaller than N, pick the biggest
* apple, set it's weight to '-1', update the other weights;
* Complexy: O(H/N * nlong); */
while ((current_height <= H) && (count < ceil))
{
qsort(fr, N, sizeof(fruit), compare_fruit);
for (i = N-1; i >= 0; i--)
printf("%3d%c", fr[i].weight, (i)? ' ':'\n');
for (i = N-1; i >= 0; i--)
printf("%3d%c", fr[i].height, (i)? ' ':'\n');
if (fr[N-1].weight == -1) break;
current_weight += fr[N-1].weight;
current_height += U;
count++;
printf("Added apple: w = %d, h = %d, count = %d:%d\n", fr[N-1].weight, fr[N-1].height, count, ceil);
for (i = N-2; i >= 0; i--)
{
/* If the fruit taken is from a row of life span 1
* eliminate all ellements with life span 1*/
if ((fr[N-1].height + U >= H) && (fr[i].height + U >= H))
fr[i].weight = -1;
/* If index height is lesser to current height
* shorten life span by 1 */
if (fr[i].height < fr[N-1].height)
{
if ((fr[i].height + U) < H)
fr[i].height += U;
else
fr[i].weight = -1;
}
}
fr[N-1].weight = -1;
}
return current_weight;
}
int solve(fruit* fr)
{
/* Se poate rezolva mult mai eficient folosind maxheap */
if (U == 0)
return sum(fr);
int i, count = 0;
int current_height = 0, current_weight = 0;
int ceil = (H - min_height(fr))/U +1;
qsort(fr, N, sizeof(fruit), compare_fruit);
/* While the current height is smaller than the maximum height and
* the number of picked fruits is smaller than N, pick the biggest
* apple, set it's weight to '-1', update the other weights;
* Complexy: O(H/N * nlong); */
while ((current_height <= H) && (count < ceil))
{
/*can do this with dei*/
int max_weight = -1;
int pos = -1;
for (i = 0; i < N; i++)
if (fr[i].weight > max_weight)
{
max_weight = fr[i].weight;
pos = i;
}
for (i = N-1; i >= 0; i--)
printf("%3d%c", fr[i].weight, (i)? ' ':'\n');
for (i = N-1; i >= 0; i--)
printf("%3d%c", fr[i].height, (i)? ' ':'\n');
if (fr[pos].weight == -1) break;
current_weight += fr[pos].weight;
current_height += U;
count++;
printf("Added apple: w = %d, h = %d, count = %d:%d\n", fr[pos].weight, fr[pos].height, count, ceil);
for (i = N-2; i >= 0; i--)
{
/* If the fruit taken is from a row of life span 1
* eliminate all ellements with life span 1*/
if ((fr[pos].height + U >= H) && (fr[i].height + U >= H))
fr[i].weight = -1;
/* If index height is lesser to current height
* shorten life span by 1 */
if (fr[i].height < fr[pos].height)
{
if ((fr[i].height + U) < H)
fr[i].height += U;
else
fr[i].weight = -1;
}
}
fr[pos].weight = -1;
}
return current_weight;
}
int main()
{
FILE *fin, *fout;
/* Try opening files */
if (!(fin = fopen(infile, "r")))
{
fprintf(stderr, "Could not open input file.\n");
return -1;
}
if (!(fout = fopen(outfile, "w")))
{
fprintf(stderr, "Could not open output file.\n");
return -1;
}
int i, weight;
fscanf(fin, "%d %d %d", &N, &H, &U);
if (N>NMAX)
{
fprintf(stderr, "Count size out of bounds.\n");
return 1;
}
fruit* quinces;
quinces = (fruit*) malloc(N*sizeof(fruit));
for (i = 0; i < N; i++)
fscanf(fin, "%d %d", &quinces[i].height, &quinces[i].weight);
weight = solve(quinces);
fprintf(fout, "%d\n", weight);
/* Close files and free memory */
free(quinces);
fclose(fin);
fclose(fout);
return 0;
}