#include<stdio.h>
#include<stdlib.h>
typedef struct gut{
int inal, greut;
}gut;
void afisare(gut *a, int n)
{
printf("\n");
int i;
for(i =0; i< n; i++)
printf("%d Inaltime %d, Greutate %d\n", i, a[i].inal,a[i].greut);
}
int compare(const void* x,const void* y)
{
return (((gut*)x)->inal) <= (((gut*)y)->inal);
}
int h,u;
int compare1(const void* x, const void* y)
{
if(((h-(((gut*)x)->inal))/u)!=((h-(((gut*)y)->inal))/u))
if ((((gut*)x)->inal) < (((gut*)y)->inal))
return 1;
else
return -1;
else
return (((gut*)x)->greut) <= (((gut*)y)->greut);
}
int main()
{
FILE *f, *fo;
f = fopen("gutui.in", "r");
fo = fopen("gutui.out", "w");
int n, i, j;
gut *a = NULL;
fscanf(f, "%d", &n);
fscanf(f, "%d", &h);
fscanf(f, "%d", &u);
a = (gut*)malloc(n * sizeof(gut));
for(i = 0; i < n; i++)
{
fscanf(f, "%d", &a[i].inal);
fscanf(f, "%d", &a[i].greut);
}
// afisare(a,n);
qsort(a, n, sizeof(gut), compare);//ordonare descresc dupa nivele, iar daca sunt pe acelasi nivel, dupa greutate
// afisare(a,n);
// nr cate nivele sunt folosite, si cate gutui sunt pe fiecare nivel, pentru a aloca vectori pt fiecare nivel
//
//h inaltimea maxima
int *cos;
cos = (int*)malloc(n*sizeof(int));
for(i = 0; i <n; i++)
cos[i] = 0;
int min, nec =0,poz = 0;
// int h1 = h, nr_niv = 0;
while(a[nec].inal > h && nec<n) //daca nu pot fi culese, sar peste ele ca nu ma intereseaza
nec++;
// printf("\nSunt %d gutui care un pot fi culese din start\n", nec);
int k = 0;
for(i = nec; i <n; i++)
if(a[i].inal <= h)
{ poz = 0;
cos[k++] = a[i].greut;
for(j = i; j <n;j++)
a[j].inal+=u;
}
else
{
min = -1;
for(j = 0; j <k; j++)
if(min < cos[j])
{
min = cos[j];
poz = j;
}
// printf("\nMinimul este %d, pe pozitia %d\n",min,poz);
if(a[i].greut > min)
cos[poz] = a[i].greut;
}
// printf("\n In cos am %d gutui \n",k);
/*
int *nr;
nr = (int*)malloc(n * sizeof(int));
for (j = 0; j < n ; j++) //initializez cu 0
nr[j] = 0; //nr de nivele maxim (nr de gutui)
while(i < n) //complexitate O(N) - > pentru a vedea cate gutui sunt pe nivel, respectiv cate nivele sunt folosite
{
while((a[i].inal > (h1-u)) &&(a[i].inal <= h1) && i < n)
{
i++;
nr[nr_niv] ++;
}
printf("Sunt %d gutui pe niveul %d\n",nr[nr_niv], nr_niv);
nr_niv++;
h1 = h1 - u;
}
for(i = 0; i <nr_niv;i++)
printf("%d ", nr[i]);
printf("\nSunt %d nivele, dintre care %d folosite\n",(h-a[n-1].inal)/u+1 ,nr_niv);
//contoare
//
i = 0; //nr de gutui, ca sa stiu unde ma opresc
int g = 0 ; //nr de gutui pe care terbuie sa le tot iau
int in;
int *col; //gutuile colectate
col = (int*)malloc(n * sizeof(int*));
for(i = 0; i<n;i++)
col[i] = 0;
i = 0;
int nx = 0,niv;
while(a[i].inal > h && i <n)
i++;
printf("%d gutui \n",i);
int loc = 0,aux; //adun nr de gutui de pe fiecare nivel
printf("Debugging:\n");
for( niv = 0; niv < nr_niv && i < n; niv++) //parcurg nivelele
{
printf("Nr gutui ce trebuie tot luate ste %d \n",g);
loc += nr[niv];
printf("Sunt pe nivelul %d, si nr de gutui maxime pana aci este %d\n", niv, loc);
if(nr[niv] == 0) //daca pe nivelul curent nu am gutui
g++; //pun la gutui "restante", adica cate trebuie sa iau in plus de pe urm nivele
else //daca nu am gutui pe nivelul curent
if(g == 0) //daca nu am gutui restante
{
printf("\n Am luat gutuia de greutate %d \n",a[i].greut);
col[nx] = a[i].greut; //iau prima gutuie si o pun in cos
nx++; //cresc cate gutui am pus in cos
i += nr[niv]; //si trec la urmatorul nivel..ca nr de gutui
printf("Am luat prima gutuie de pe nivelul %d, si i-u urca pana la %d de greutate %d\n", niv, i,a[i].greut);
printf("Nr gutui culese pana acu este %d \n", nx);
}
else
{ aux = nr[niv];
printf("Am gutui restante de luat %d,gutui per nivel %d\n", g,aux);
while( g > 0 || aux > 0) //cat timp mai am gutui de luat de pe nivelul curent, sau mai am gutui pe nivel
{
col[nx] = a[i].greut; //le adaug la cos
nx ++; //cresc nr gutui puse in cos
aux --; //scad nr de gutui per nivel culese
i++; //trec la urmatoarea gutuie
g--; //scad nr de gutui restante
printf("Gutui restante ramase %d , gutui culese %d, gutuia la care sunt %d, gutui ramase per nivel %d\n",g,nx,i,aux);
}
if( g == 0 && aux > 0) //daca am terminat nr de gutui restante de cules, dar mai am pe nivel
{
col[nx] = a[i].greut;//mai culeg una de pe nivelul curent,
nx++;
while(i<loc) //cresc i-u pana depasesc nivelul
i++;
printf("Gutui restante nu sunt, sunt la gutuia %d \n",i);
if(aux == 0)
g++;
// if(g < 0)
// g = 0;
}
}
}
*/
/*
while(i < n)
{
in = (h - a[i].inal)/u; //nivelul pe care este gutuia i
if(in == 0) //daca am nivelul initial
{
if(nr[in] != 0) //daca nivelul un este gol
{
col[nx++] = a[i].greut; //iau prima gutuie, ca e cea mai grea
i += nr[in]; //trec peste celelalte de pe acest nivel
}
else
g = 1; //daca nivelul este gol, inseamna ca trebuie luata de mai jos in plus cu o gutuie
}
else //daca nu sunt pe primul nivel
{ printf("si aci\n");
if(nr[in] != 0) //daca nivelul este gol
{
if( g == 0) //daca nu am gutui de luat restante
{
col[nx++] = a[i].greut; //iau prima gutuie de aci
i += nr[in];
}
else
while( g > 0 || nr[in] > 0) //daca mai am gutuie de luat, cat timp mai am restante, sau cat timp mai am gutui pe nivel, le pun in cos
{
col[nx++] = a[i].greut;
i++;
}
}
else
g++; //daca nivelul este go, mai adaug gutui restante
}
}
*/
int s = 0;
for(i =0; i<k; i++)
{
s += cos[i];
}
// printf("Suma maxima este: %d \n",s);
fprintf(fo, "%d",s);
free(a);
fclose(f);
fclose(fo);
return 0;
}