#include <stdio.h>
#include <malloc.h>
const char *fin="gutui.in";
const char *fout="gutui.out";
long int N,H,U,GG,indice;
// Functie pentru citire si validare numarului de gutui N
void readn()
{
FILE *f;
f=fopen(fin,"r");
fscanf(f,"%ld %ld %ld",&N,&H,&U);
fclose(f);
}
// Functie pentru citirea din fisierul gutui.in a vectorilor inaltimilor si
// greutatilor
void readf(int *pg, int *ph)
{
FILE *f;
long int i,j;
f=fopen(fin,"r");
fscanf(f,"%ld %ld %ld",&N,&i,&j);
for(i=0;i<N;i++)
fscanf(f,"%ld %ld",ph+i,pg+i);
fclose(f);
}
// Functie pentru determinarea gutuii care urmeaza a fi culeasa
// exist = 1 daca inaltimea la care se va afla gutuia i depaseste pe H
long int max1(long int *p, long int *h,long int *g)
{
long int i,max;
i=0;
while(*(p+i) == -1) //actualizare vector culese
i++;
max=*(g+i); //prima val diferita de -1 din culese
indice=i;
for(i=0;i<N;i++)
if(max<*(g+i) && *(h+i)+U>H && *(p+i)!=-1)
{
max=*(g+i);
indice=i;
}
return max;
}
long int max2(long int *p, long int *h, long int *g)
{
long int i,max;
i=0;
while(*(p+i) == -1)
i++;
max=*(h+i);
indice=i;
for(i=0;i<N;i++) //gasim maximul dintre inaltimi
{
if(max<*(h+i) && *(p+i)!=-1)
{
max=*(h+i);
indice=i;
}
}
max=*(g+indice);
return max;
}
// Functie pentu initializare cu 0 a vectorului culese
void init(long int *p)
{
long int i;
for(i=0;i<N;i++)
*(p+i)=0;
}
// Functie pentru actualizarea vectorului culese
void ramase(long int *p, long int *h)
{
long int i;
for(i=0;i<N;i++)
if(*(h+i)>H)
*(p+i)=-1;
}
// Functie pentru determinarea numarului de gutui care pot fi culese
long int testculese(long int *p)
{
long int i,decules=0;
for(i=0;i<N;i++)
if(*(p+i)!= -1)
decules++;
return decules;
}
// Functie pentru actualizarea vectorului culese
void update(long int *p)
{
*(p+indice)=-1;
}
// Functie pentru actualizarea inaltimilor
void updateh(long int *p, long int *h)
{
long int i;
for(i=0;i<N;i++)
if(*(p+i)!=-1)
*(h+i)+=U;
}
// Functie pentru rezolvarea problemei gutuilor
// hg este vectorul inaltimilor
// mg este vectorul maselor
// masa = masa curenta a gutuilor culese
// cules = vectorul care are pe pozitia i valoarea 0 daca gutuia i poate
// fi culeasa ( se afla la o inaltime mai mica decat H)
// si are valoarea -1 daca gutuia de pe pozitia i ori se afla la
// o inaltime mai mare decat H, ori a fost culeasa
long int gutui(long int *mg, long int *hg)
{
long int i,*cules;
GG=0;
cules=(long int *)malloc(N*sizeof(long int));
init(cules); //vector culese este 0
ramase(cules,hg);//cate gutui mai pot fi culese
//printf(" Mai sunt %d gutui \n",testculese(cules));
while(testculese(cules))
{
i=indice;
if(*(hg+i)+U>H)
GG+= max1(cules,hg,mg); //gutuia cea mai buna
else
GG+= max2(cules,hg,mg);
update(cules);
updateh(cules,hg);
ramase(cules,hg);
//printf(" Se culege gutuia %d \n Masa totala %d \n",indice,GG);
//printf(" Mai sunt %d gutui \n",testculese(cules));
//for(i=0;i<N;i++)
//printf(" cules[%d] = %d \n",i,*(cules+i));
}
return GG;
}
// Functie pentru scrierea solutiei in fisierul gutui.out
void writef()
{
FILE *f;
f=fopen(fout,"w");
fprintf(f,"%ld",GG);
fclose(f);
}
// n = numar de gutui din copac
// H = inaltimea la care poate ajunge culegatorul
// U = inaltimea cu care se ridica crengile dupa culegerea unei gutui
// pg = pointer catre vectorul maselor gutuilor
// ph = pointer catre vectorul inaltimilor la care se afla initial gutuile
// GG = masa totala a gutuilor culese
int main()
{
long int *pg,*ph;
readn();
pg=(long int *)malloc(N*sizeof(long int));
ph=(long int *)malloc(N*sizeof(long int));
readf(pg,ph);
GG=gutui(pg,ph);
writef();
return 0;
}