// LISっぽいが、重みが付いている
// ほぼ解説をみてしまったのであれだが、インラインDPでできる

// 状態: 高さhと座標i, O(N^2) ただしiは陽に持たない(「時刻」)ので O(N)
// 結果: hで終わるiまでの増加列に限定した解
// 遷移: 普通にやると O(N) だがデータ構造を使うことで O(log N)

#pragma region Header
#ifdef DEBUG
#include "debug.hpp"
#else
#define debug(...)
#define IFD(...)
#ifndef NDEBUG
#define NDEBUG
#endif
#endif
#include <utility>
#include <cstdint>
#include <cmath>
#include <cassert>
#include <vector>
#include <array>
#include <deque>
#include <queue>
#include <stack>
#include <tuple>
#include <set>
#include <map>
#include <unordered_map>
#include <bitset>
#include <string>
#include <functional>
#include <algorithm>
#include <numeric>
#include <stdexcept>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <boost/hana/functional/fix.hpp>
using boost::hana::fix;
using namespace std;
using i32 = int32_t;
using i64 = int64_t;
using u32 = uint32_t;
using u64 = uint64_t;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repd(i, n) for (int i = (n)-1; i >= 0; --i)
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define FORD(i, b, a) for (int i = (b); i >= (a); --i)
template <typename T>
int SZ(T const &x)
{
    return static_cast<int>(x.size());
}
template <class T>
bool chmax(T &a, T const &b)
{
    if (a < b)
    {
        a = b;
        return true;
    }
    return false;
}
template <class T>
bool chmin(T &a, T const &b)
{
    if (b < a)
    {
        a = b;
        return true;
    }
    return false;
}
#pragma endregion

struct intvl
{
    int l;
    int r;
};

struct mon
{
    using T = i64;
    static T op(T a, T b)
    {
        return max(a, b);
    }
    static inline T id = 0;
};

// セグメント木
template <typename M>
struct seg_tree
{
    int n;
    using T = typename M::T;

private:
    vector<T> data;

    // ノードから区間への対応
    vector<intvl> intvl_s;

    // ノードの端点を得る
    intvl const &intvl_of_node(int const i)
    {
        return intvl_s[i];
    }

    // (2ベキでないときに出てくる)不要なノードならfalse
    bool is_valid_node(int const i)
    {
        intvl lr = intvl_of_node(i);
        return lr.l < lr.r;
    }

    // ノードから区間の端点への対応を前計算
    void init_intvl_s()
    {
        rep(i, n)
        {
            intvl_s[n + i] = {i, i + 1};
        }
        for (int i = n - 1; i >= 1; i--)
        {
            intvl_s[i] = {intvl_s[2 * i].l, intvl_s[2 * i + 1].r};
        }
    }

public:
    // idで初期化
    explicit seg_tree(int const size)
        : n(size), data(2 * size, M::id), intvl_s(2 * size)
    {
        init_intvl_s();
    }

    // a_sで初期化
    seg_tree(int const size, vector<T> const &a_s)
        : n(size), data(2 * size, M::id), intvl_s(2 * size)
    {
        init_intvl_s();

        rep(i, n)
        {
            data[n + i] = a_s[i];
        }
        for (int i = n - 1; i >= 1; i--)
        {
            if (not is_valid_node(i))
            {
                continue;
            }
            data[i] = M::op(data[2 * i], data[2 * i + 1]);
        }
    }

    // i番目をaに変更
    void set(int i, T const a)
    {
        i += n;
        data[i] = a;
        while (i > 1)
        {
            i /= 2;
            if (not is_valid_node(i))
            {
                break;
            }
            data[i] = M::op(data[2 * i], data[2 * i + 1]);
        }
    }

    // [l,r)の取得
    T query(intvl const lr)
    {
        int l = lr.l, r = lr.r;
        l += n;
        r += n;
        T retl = M::id, retr = M::id;
        while (l < r)
        {
            if (l & 1)
            {
                retl = M::op(retl, data[l]);
                ++l;
            }
            if (r & 1)
            {
                --r;
                retr = M::op(data[r], retr);
            }
            l /= 2;
            r /= 2;
        }
        return M::op(retl, retr);
    }

    // iの取得
    T at(int const i)
    {
        return data[i + n];
    }
};

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int n;
    cin >> n;
    vector<int> h_s(n);
    rep(i, n)
    {
        cin >> h_s[i];
        --h_s[i];
    }
    vector<i64> a_s(n);
    rep(i, n) { cin >> a_s[i]; }

    seg_tree<mon> dp(n);
    rep(i, n) {
        auto a = dp.query({0, h_s[i]});
        auto b = dp.at(h_s[i]);
        dp.set(h_s[i], mon::op(b, a + a_s[i]));
    }

    cout << dp.query({0, dp.n}) << '\n';

    return 0;
}


Measured memory_bytes: 11888