#include<stdio.h>
#include<malloc.h>
typedef struct {
unsigned int inaltime;
unsigned int greutate;
} gutuie;
//interschimba 2 elemente din vectorul de gutui
void swap(gutuie *a, gutuie *b) {
gutuie aux;
aux=*a;
*a=*b;
*b=aux;
}
//auxiliar pentru functia de sortare quicksort
int choose_pivot(int i, int j) {
return ((i+j)/2);
}
//sorteaza descrescator in functie de greutate in vectorul de gutui
void qsort(gutuie *g, int m, int n) {
int key,i,j,k;
if (m<n)
{
k=choose_pivot(m,n);
swap(&g[m],&g[k]);
key=g[m].greutate;
i=m+1;
j=n;
while (i<=j)
{
while ((i<=n)&&(g[i].greutate>=key))
i++;
while ((j>=m) &&(g[j].greutate<key))
j--;
if (i<j)
swap(&g[i],&g[j]);
}
swap(&g[m],&g[j]);
qsort(g,m,j-1);
qsort(g,j+1,n);
}
}
void insert(unsigned int *maxime, unsigned int *nrg, unsigned int n, unsigned int x, unsigned int poz) {
unsigned int i;
//printf("n=%u, poz=%u\n",n,poz);
for (i=n;i>=poz;)
{
//printf("i=%d maxime[i]=%u\n",i,maxime[i]);
maxime[i+1]=maxime[i];
nrg[i+1]=nrg[i];
if (i>0) i--;
else break;
}
maxime[poz]=x;
if (poz) {
nrg[poz]=maxime[poz]-maxime[poz-1]-1;
nrg[poz+1]=maxime[poz+1]-maxime[poz]-nrg[poz+1];
}
else {
nrg[poz]=maxime[poz];
nrg[poz+1]-=nrg[poz]+1;
}
}
int main() {
//DECLARARI VARIABILE
unsigned int n,h,u,i,gt=0,cnt=0,j,localizare=0;
FILE *in=fopen("gutui6.in","r");
FILE *out=fopen("gutui.out","w");
fscanf(in,"%d",&n);
//ALOCARI DE MEMORIE
gutuie *g=(gutuie*)malloc(n*sizeof(gutuie));
unsigned int *ord=(unsigned int*)malloc(n*sizeof(unsigned int));
unsigned int *maxime=(unsigned int*)malloc(n*sizeof(unsigned int));
unsigned int *nrg=(unsigned int*)malloc(n*sizeof(unsigned int));
//CITIRE DIN FISIER SI COMPLETARE CAMPURI GUTUI
fscanf(in,"%u%u",&h,&u);
for (i=0;i<n;i++)
fscanf(in,"%u%u",&g[i].inaltime,&g[i].greutate);
/*
for (i=0;i<n;i++)
printf("%d %d\n",g[i].inaltime,g[i].greutate);
printf("\n");
*/
qsort(g,0,n-1);
for (i=0;i<n;i++)
printf("%d %d\n",g[i].inaltime,g[i].greutate);
printf("\n");
//formez vectorul ord
for (i=0;i<n;i++) {
// if (g[i].inaltime>h)
// ord[i]=-1;
// else
ord[i]=(h-g[i].inaltime)/u;
}
for (i=0;i<n;i++)
printf("%u ",ord[i]);
printf("\n");
maxime[0]=nrg[0]=ord[0];
gt=g[0].greutate;
/*
for (i=1;i<n;i++)
//if (ord[i]!=-1) {
{
if (ord[i]>maxime[cnt]) {
maxime[++cnt]=ord[i];
nrg[cnt]=maxime[cnt]-maxime[cnt-1];
gt+=g[i].greutate;
nrg[cnt]--;
}
else {
//localizare=-1;
for (j=0;j<=cnt;j++) {
if (ord[i]<=maxime[j]) {localizare=j;break;}
}
//while (localizare>=0) {
for (;;) {
if (nrg[localizare]>0) {
gt+=g[i].greutate;
nrg[localizare]--;
break;
}
else
{
if (localizare==0) break;
localizare--;
}
}
}
}
// }
*/
//probabil mai am de implementatcazul in care se imprumuta de la precedentele
unsigned int ctrl;
for (i=1;i<n;i++) {
ctrl=0;
int poz_av=-1;
for (j=0;j<=cnt;j++) {
if (nrg[j]!=0) {
//printf("%u diferit\n",j);
poz_av=j;
}
if (maxime[j]==ord[i])
{
ctrl=1;
if (nrg[j]>0) {
nrg[j]--;
gt+=g[i].greutate;
break;
}
else {
if (poz_av!=-1) {
nrg[poz_av]--;
gt+=g[i].greutate;
break;
}
}
}
}
if (ctrl==0) {
for (j=0;j<=cnt;j++) {
if (j==0 && ord[i]<=maxime[0]) {
insert(maxime,nrg,cnt,ord[i],0);
gt+=g[i].greutate;
cnt++;
ctrl=1;
break;
}
else if (j!=0 && ord[i]>maxime[j-1] && ord[i]<=maxime[j]) {
insert(maxime,nrg,cnt,ord[i],j);
gt+=g[i].greutate;
cnt++;
ctrl=1;
break;
}
}
if (ctrl==0)
{
maxime[++cnt]=ord[i];
nrg[cnt]=maxime[cnt]-maxime[cnt-1];
gt+=g[i].greutate;
nrg[cnt]--;
}
}
for (j=0;j<=cnt;j++)
printf("%u ",maxime[j]);
printf("\n");
for (j=0;j<=cnt;j++)
printf("%u ",nrg[j]);
printf("\n");
printf("---------------------------------------\n");
}
fprintf(out,"%u\n",gt);
return 0;
}