#include using namespace std; #define rep(i, a, b) for(int i = a; i < (b); ++i) #define trav(a, x) for(auto& a : x) #define all(x) x.begin(), x.end() #define sz(x) (int)(x).size() typedef long long ll; typedef pair pii; typedef pair pll; typedef vector vi; typedef vector vl; typedef long double ld; const ll big = 1000000007; struct Tree { typedef ll T; static constexpr T unit = big*big; T f(T a, T b) { return min(a, b); } // (any associative fn) vector s; int n; Tree(int n = 0, T def = unit) : s(2*n, def), n(n) {} void update(int pos, T val) { for (s[pos += n] = val; pos /= 2;) s[pos] = f(s[pos * 2], s[pos * 2 + 1]); } T query(int b, int e) { // query [b, e) T ra = unit, rb = unit; for (b += n, e += n; b < e; b /= 2, e /= 2) { if (b % 2) ra = f(ra, s[b++]); if (e % 2) rb = f(s[--e], rb); } return f(ra, rb); } }; int n; const int MAXN = 1001; vl F,T,ind; ll ma_f = 0; bool comp(int i, int j){ return T[i] < T[j]; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; rep(c1,0,n){ ll f,t; cin >> f >> t; F.push_back(f); T.push_back(t); ind.push_back(c1); ma_f = max(f, ma_f); } sort(all(ind), comp); Tree ODD(ma_f/2+1, 0); Tree EVEN(ma_f/2+1, 0); rep(c2,0,ma_f/2+1){ EVEN.update(c2, ll(2*c2)*T[ind[0]]); ODD.update(c2, ll(2*c2+1)*T[ind[0]]); } ll ans = 0; rep(c1,0,n){ vl odd, even; for(ll free = 0; free <= ma_f+(ma_f+1)%2; free++){ int i = ind[c1]; int parity = abs(free-F[i])%2; ll lo = abs(F[i]-free)/2; ll hi = min(ma_f/2, (F[i]+free)/2); ll q; if(parity == 0){ q = EVEN.query(lo,hi+1); } else{ q = ODD.query(lo,hi+1); } if(free%2 == 1){ odd.push_back( ( T[i]*(F[i] - free) + q) / 2); } else{ even.push_back( ( T[i]*(F[i] - free) + q) / 2); } } if(c1 == n-1){ ans = even[0]; break; } assert(sz(odd) == ma_f/2+1); assert(sz(even) == ma_f/2+1); rep(c2,0,ma_f/2+1){ EVEN.update(c2, 2*even[c2] + ll(2*c2)*T[ind[c1+1]]); ODD.update(c2, 2*odd[c2] + ll(2*c2+1)*T[ind[c1+1]]); } } cout << ans << "\n"; return 0; }