#include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define FOR(i,a,b) for (int i=(a),for_##i##_max=(b);i<=(for_##i##_max);++i)
#define RFOR(i,a,b) for (int i=(a),rfor_##i##_min=(b);i>=(rfor_##i##_min);--i)
#define REP(i,n) for (int i=0,rep_##i##_len=(n);i<(rep_##i##_len);++i)
#define RREP(i,n) for (int i=(n)-1;i>=0;--i)

namespace { // Basics

template<typename T>
void chmin(T &x, T y) {
  x = std::min(x, y);
}

template<typename T>
void chmax(T &x, T y) {
  x = std::max(x, y);
}

template<typename T>
__attribute__((unused))
const auto minimum = static_cast<T const &(*)(T const &, T const &)>(std::min);

template<typename T>
__attribute__((unused))
const auto maximum = static_cast<T const &(*)(T const &, T const &)>(std::max);

template<typename T>
int cmp3(T lhs, T rhs) { return (lhs == rhs) ? 0 : (lhs > rhs) ? 1 : -1; }

template<typename T>
__attribute__((unused))
T constexpr infty = std::numeric_limits<T>::max / 3;
template<>
__attribute__((unused))
auto constexpr infty<int> = 1'100'100'100;
template<>
__attribute__((unused))
auto constexpr infty<long long int> = 100'500'400'300'200'100LL;

using lli = long long int;
using ld = long double;

} // namespace
namespace { // segment-tree

template<typename T, typename FnT>
class segment_tree {
  public:
    explicit segment_tree(FnT const &app, T const &un, size_t size):
      segment_tree(app, un, std::vector<T>(size, un)) {
    }
    explicit segment_tree(FnT const &app, T const &un, std::vector<T> const &v):
      append(app), unit(un), N(1 << log2(v.size())), dat(2*N-1) {
      std::copy(begin(v), end(v), begin(dat)+N-1);
      for (size_t k = N - 1; k > 0; --k) {
        dat[k-1] = append(dat[2*k-1], dat[2*k]);
      }
    }
    void update(size_t k, T x) {
      k += N - 1;
      dat[k] = x;
      while (k > 0) {
        k = (k - 1) / 2;
        dat[k] = append(dat[2*k+1], dat[2*k+2]);
      }
    }
    T at(size_t k) const {
      return dat[k+N-1];
    }
    T query(size_t a, size_t b, size_t k, size_t l, size_t r) const {
      if (r <= a || b <= l) { return unit; }
      if (a <= l && r <= b) { return dat[k]; }
      const auto mid = (l + r) / 2;
      const auto vl = query(a, b, 2*k+1, l, mid);
      const auto vr = query(a, b, 2*k+2, mid, r);
      return append(vl, vr);
    }
    T query(size_t a, size_t b) const {
      return query(a, std::min(b, N), 0, 0, N);
    }
    T query() const {
      return query(0, N, 0, 0, N);
    }
    std::vector<T> const &data() const { return dat; }
  private:
    FnT const append;
    T const unit;
    size_t const N;
    std::vector<T> dat;

    static size_t log2(size_t n) {
      size_t p = 1;
      while ((1 << p) < n) { ++p; }
      return p;
    }
};

template<typename T, typename FnT>
segment_tree<T, typename std::decay<FnT>::type>
make_segment_tree(FnT const &app, T const &un, size_t size) {
  return segment_tree<T, typename std::decay<FnT>::type>(app, un, size);
}

template<typename T, typename FnT>
segment_tree<T, typename std::decay<FnT>::type>
make_segment_tree(FnT const &app, T const &un, std::vector<T> const &v) {
  return segment_tree<T, typename std::decay<FnT>::type>(app, un, v);
}

} // namespace

using namespace std;

void solve(int N, vector<lli> const &Hs, vector<lli> const &As) {
  auto segt = make_segment_tree<lli>(maximum<lli>, 0, N+1);
  REP(i, N) {
    auto const top = segt.query(0, Hs[i]);
    segt.update(Hs[i], top + As[i]);
  }
  cout << segt.query() << endl;
}

int main() {
  // cout << fixed << setprecision(10);

  int N; cin >> N;
  vector<lli> Hs;
  REP(i, N) {
    lli H;
    cin >> H;
    Hs.push_back(H);
  }
  vector<lli> As;
  REP(i, N) {
    lli A;
    cin >> A;
    As.push_back(A);
  }
  solve(N, Hs, As);
  return 0;
}


Measured memory_bytes: 10096