#include <iostream>
#include <string>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <functional>
#include <map>
#include <set>

using namespace std;

typedef long long i64;
typedef vector<i64> vi;
typedef vector<vi> vvi;

typedef pair<i64, i64> pi;

#define tr(c, i) for(auto i = (c).begin(); i != (c).end(); i++)
#define pb push_back
#define sz(a) int((a).size())
#define all(c) (c).begin(), (c).end()
#define REP(s, e, i) for(i=(s); i < (e); ++i)


struct SegTree {
  ///
  using value_type = long long;
  using index_type = vector<value_type>::size_type;
  static const value_type merge(const value_type &v1, const value_type &v2) {
    return v1 + v2;
  }
  static const value_type update_elem(const value_type &current_value, const value_type &updated_value) {
    return current_value + updated_value;
  }
  static const value_type update_lazy(const value_type &lazy_cur, const value_type &lazy_up) {
    return lazy_cur + lazy_up;
  }
  static const value_type apply_lazy(const value_type &value, const value_type &lazy, i64 nl, i64 nr) {
    return value + lazy * (nr - nl);
  }
  const value_type default_value = 0;
  ///

  vector<value_type> data, lazy;
  index_type n;
  
  SegTree(i64 n_) {
    i64 s = 1;
    while(s < n_) {
      s *= 2;
    }
    n = s;
    data.resize(s * 2 - 1, default_value);
    lazy.resize(s * 2 - 1, default_value);
  }

  value_type query(index_type l, index_type r, index_type nid, index_type nl, index_type nr) {
    lazy_eval(nid, nl, nr);
    if(nr <= l || r <= nl) {
      return default_value;
    }
    
    if(l <= nl && nr <= r) {
      return data[nid];
    }
    else {
      value_type vl = query(l, r, nid*2+1, nl, (nl+nr)/2);
      value_type vr = query(l, r, nid*2+2, (nl+nr)/2, nr);
      return merge(vl, vr);
    }
  }  
  value_type query(index_type l, index_type r) {
    return query(l, r, 0, 0, n);
  }

  void update(index_type i, value_type x) {
    i += n-1;
    data[i] = update_elem(data[i], x);
    while(i > 0) {
      i = (i - 1) / 2;
      data[i] = merge(data[i*2+1], data[i*2+2]);
    }
  }

  void lazy_eval(index_type nid, index_type nl, index_type nr) {
    if(lazy[nid] != default_value) {
      data[nid] = apply_lazy(data[nid], lazy[nid], nl, nr);
      if(nr - nl > 1) {
	lazy[nid*2+1] = update_lazy(lazy[nid*2+1], lazy[nid]);
	lazy[nid*2+2] = update_lazy(lazy[nid*2+2], lazy[nid]);
      }
      lazy[nid] = default_value;
    }
  }
  
  void range_update(index_type l, index_type r, value_type x, index_type nid, index_type nl, index_type nr) {    
    lazy_eval(nid, nl, nr);    
    if(nr <= l || r <= nl) {
      return;
    } 

    if(l <= nl && nr <= r) {      
      lazy[nid] = x;
      lazy_eval(nid, nl, nr);
    }
    else {
      range_update(l, r, x, nid*2+1, nl, (nl+nr)/2);
      range_update(l, r, x, nid*2+2, (nl+nr)/2, nr);
      data[nid] = merge(data[nid*2+1], data[nid*2+2]);
    }
  }
  
  void range_update(index_type l, index_type r, value_type x) {
    range_update(l, r, x, 0, 0, n);
  }
};


int main(int argc, char *argv[]) {
  i64 N, D, A, i;
  cin >> N >> D >> A;
  vector<pi> XH(N);
  REP(0, N, i) {
    cin >> XH[i].first >> XH[i].second;
  }
  sort(all(XH));

  /*
  REP(0, N, i) {
    cout << XH[i].first << " " << XH[i].second << endl;;
  }
  */

  SegTree tree(N);
  i64 ans = 0;
  REP(0, N, i) {
    i64 H = tree.query(i, i+1);
    //cout << "Q " << H << " " << XH[i].second << " " << XH[i].second - H << endl;
    if(H < XH[i].second) {
      i64 HR = XH[i].second - H;
      i64 C = HR / A;
      if(HR % A != 0)
	C++;
      
      i64 V = C * A;
      ans += C;
      auto it = lower_bound(all(XH), pi(XH[i].first + D * 2 + 1, 0));
      i64 R = it - XH.begin();
      tree.range_update(i, R, V);
      //cout << XH[i].first << " " << XH[i].first + D * 2 << " " << i << " " << R << " " << C << " " << V << endl;
    }
  }
  cout << ans << endl;

  /*
  {
    vector<pi> XH2 = XH;
    i64 j, ans2 = 0;
    REP(0, N, i) {
      //cout << "Q " << XH2[i].second << endl;
      if(XH2[i].second > 0) {
	i64 C = XH2[i].second / A;
	if(XH2[i].second % A != 0) {
	  C++;
	}
	i64 V = C * A;
	ans2 += C;
	REP(i, N, j) {
	  if(XH2[j].first <= XH2[i].first + D * 2) {
	    XH2[j].second -= V;
	    //cout << "reduce " << j << " " << XH2[j].first << " " << XH2[j].second << endl;
	  }
	  else {
	    break;
	  }
	}
      }
    }
    cout << ans2 << endl;
  }
  */
  
  return 0;
}


Measured memory_bytes: 11520