#include<stdio.h>
#include<stdlib.h>
//#include<conio.h>
typedef struct gutui{
int g;
int h;
}gutui;
void citire(FILE *f,gutui *a,int n){ //citire vector de structuri din fisier
int i;
int aux;
for(i=0;i<n;i++){
fscanf(f,"%d",&a[i].h);
fscanf(f,"%d",&a[i].g);
}
}
int comparare(const void *a,const void *b){ //functia de comparare folosita pentru sortarea descrescatoare a vectorului de structuri in ordinea inaltimilor
gutui *a1,*b1;
a1=(gutui*)a;
b1=(gutui*)b;
float rez1,rez2;
return (*b1).h-(*a1).h;
}
float minim(gutui *v,int n,int *gr,int *poz){ //returneaza minimul din vector
int i;
float min=(float)v[0].g/v[0].h;
for(i=0;i<n;i++){
if( ( (float)v[i].g/v[i].h ) < min){
min=(float)v[i].g/v[i].h;
(*poz)=i; //pozitia elementului minim
(*gr)=v[i].g; //greutatea elementului minim
}//if
}//for
return min;
}
int nivel(int h,int hmax,int u){
if(h < hmax) return h/u; //daca inaltimea nu depaseste inaltimea maxima, intoarce nivelul
return -1; //altfel, intoarce -1 (depasire)
}
int greutate(gutui *v,int n,int hmax,int u){ //parcurge vectorul ordonat (dupa inaltimi) de structuri v pentru a gasi greutatea maxima
gutui *r=(gutui*)calloc(n,sizeof(gutui)); //vector care pastreaza structurile cu valorile cele mai bune pentru raportul greutate/inaltime
int i,j=0;
int gr=0;
int poz=0;
int gmax = v[0].g;
int nc=nivel(v[0].h,hmax,u); //nivelul cel mai de sus
printf("asta e nivelul %d\n",nc);
r[0]=v[0]; //adauga primul element in vector
i=1;
j=1;
while(i < n) { //pentru fiecare gutuie
while( nivel((v[i].h+j*u),hmax,u) == nc){ //adauga in vector gutuile accesibile de pe nivelul curent
printf("asta e nivelul %d\n",nc);
//getch();
r[j].g=v[i].g;
r[j].h=(v[i].h+j*u); //la pasul j, inaltimea tuturor gutuilor este cu j*u mai mare decat cea initiala
gmax += v[i].g;
i++;
j++;
}
if(i>=n) break;
if(nivel((v[i].h+j*u),hmax,u)!=-1) { //nu exista gutui care sa fi devenit inaccesibile pe nivelul analizat, treci la nivelul urmator ( h nu a devenit mai mare decat hmax )
nc=nivel((v[i].h+j*u),hmax,u);
printf("nu s-a depasit hmax!\n");
//getch();
}
else{
while(nivel((v[i].h+j*u),hmax,u) == -1){ //restul de gutui de pe nivel au devenit inaccesibile (h > hmax), dar pot fi o alegere mai buna
if(i>=n) break;
if( (float)v[i].g/ (v[i].h+j*u) > minim(r,j,&gr,&poz) ) { //elementul curent este mai bun decat cel mai prost element din vector
printf("s-a intrat in zona asta\n");// getch();
gmax -= gr;
gmax += v[i].g;
r[poz].g= v[i].g;
r[poz].h=(v[i].h+j*u); //inlocuieste si in vector minimul cu noua valoare
j++;
}//if
i++;
}//while
}//else
}//while
return gmax;
}
void scriere(FILE *f,gutui *a,int n){ //scriere vector de structuri din fisier
int i;
int aux;
for(i=0;i<n;i++){
fprintf(f,"inaltimea:");
fprintf(f,"%d",a[i].h);
fprintf(f," "); //write spatiu
fprintf(f,"greutatea:");
fprintf(f,"%d",a[i].g);
fprintf(f,"\n"); //write newline
}
}
int main(){
gutui *v;
int gmax;
int aux,hmax,u;
int n;
FILE *f,*g;
f=fopen("gutui.in","rt");
g=fopen("gutui.out","wt");
fscanf(f,"%d",&n); //citire numar gutui
fscanf(f,"%d",&hmax); //citire inaltime maxima
fscanf(f,"%d",&u); //citire inaltime cu care se ridica crengile la fiecare gutuie culeasa;
v=(gutui*)malloc(n*sizeof(gutui)); //alocare memorie pentru vectorul de structuri
citire(f,v,n); //citire perechi gutuie-inaltime din fisier
// scriere(g,v,n);
fprintf(g,"\n\n");
qsort(v,n,sizeof(gutui),comparare);
gmax=greutate(v,n,hmax,u);
printf("%d",gmax);
// getch();
//scriere(g,v,n);
fclose(f);
fclose(g);
}