#include <iostream>
#include <queue>
#include <map>
#include <deque>
#include <algorithm>
#include <set>
#include <string>
#include <math.h>
#include <stdio.h>
#include <iomanip>
#include <cstring>
#include <climits>
#include <iostream>


#define ll long long
#define p 1000000007
using namespace std;

std::map<ll,ll>::iterator lessthan(map<ll,ll> &mp, ll k){

    std::map<ll,ll>::iterator it = mp.lower_bound(k);
    if(it != mp.begin()) {
        return --it;
    }
    return mp.end();
}
ll factorial(ll n)
{
    if (n == 1 || n == 0)
        return 1;
    return  n * factorial(n - 1);
}
#define endl '\n'
// A utility function to get the
// middle index of given range.
ll getMid(ll s, ll e)
{
    return s + (e - s) / 2;
}

/*  A recursive function to get the sum of
    values in given range of the array.
    The following are parameters for this
    function.

    st       -> Pointer to segment tree
    node     -> Index of current node in
                the segment tree .
    ss & se  -> Starting and ending indexes
                of the segment represented
                by current node, i.e., st[node]
    l & r    -> Starting and ending indexes
                of range query */
ll MaxUtil(ll* st, ll ss, ll se, ll l,
            ll r, ll node)
{
    // If segment of this node is completely
    // part of given range, then return
    // the max of segment
    if (l <= ss && r >= se)
        return st[node];

    // If segment of this node does not
    // belong to given range
    if (se < l || ss > r)
        return -1;

    // If segment of this node is partially
    // the part of given range
    ll mid = getMid(ss, se);

    return max(MaxUtil(st, ss, mid, l, r,
                       2 * node + 1),
               MaxUtil(st, mid + 1, se, l,
                       r, 2 * node + 2));
}

/* A recursive function to update the nodes which
   have the given index in their range. The following
   are parameters st, ss and se are same as defined
   above index -> index of the element to be updated.*/
void updateValue(ll arr[], ll* st, ll ss, ll se,
                 ll index, ll value, ll node)
{
    if (index < ss || index > se)
    {
        cout << "Invalid Input" << endl;
        return;
    }

    if (ss == se)
    {
        // update value in array and in segment tree
        arr[index] = value;
        st[node] = value;
    }
    else {
            ll mid = getMid(ss, se);

            if (index >= ss && index <= mid)
                updateValue(arr, st, ss, mid, index,
                            value, 2 * node + 1);
            else
                updateValue(arr, st, mid + 1, se,
                            index, value, 2 * node + 2);

            st[node] = max(st[2 * node + 1],
                       st[2 * node + 2]);
    }
    return;
}

// Return max of elements in range from
// index l (query start) to r (query end).
ll getMax(ll* st, ll n, ll l, ll r)
{
    // Check for erroneous input values
    if (l < 0 || r > n - 1 || l > r)
    {
        printf("Invalid Input");
        return -1;
    }

    return MaxUtil(st, 0, n - 1, l, r, 0);
}

// A recursive function that constructs Segment
// Tree for array[ss..se]. si is index of
// current node in segment tree st
ll constructSTUtil(ll arr[], ll ss, ll se,
                    ll* st, ll si)
{
    // If there is one element in array, store
    // it in current node of segment tree and return
    if (ss == se)
    {
        st[si] = arr[ss];
        return arr[ss];
    }

    // If there are more than one elements, then
    // recur for left and right subtrees and
    // store the max of values in this node
    ll mid = getMid(ss, se);

    st[si] = max(constructSTUtil(arr, ss, mid, st,
                                 si * 2 + 1),
                 constructSTUtil(arr, mid + 1, se,
                                 st, si * 2 + 2));

    return st[si];
}

/* Function to construct segment tree from given array.
   This function allocates memory for segment tree.*/
ll* constructST(ll arr[], ll n)
{
    // Height of segment tree
    ll x = (ll)(ceil(log2(n)));

    // Maximum size of segment tree
    ll max_size = 2 * (ll)pow(2, x) - 1;

    // Allocate memory
    ll* st = new ll[max_size];

    // Fill the allocated memory st
    constructSTUtil(arr, 0, n - 1, st, 0);

    // Return the constructed segment tree
    return st;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    //map<ll,ll>mp;
    ll n;
    cin >> n;
    ll h[n];
    ll c[n];
    ll dp[n+1];
    for (ll i = 0; i < n; i++) cin >> h[i];
    for (ll j = 0; j < n; j++) cin >> c[j];
    for (ll i = 0; i <= n; i++)
        dp[i] = 0;
    //dp[4] = 5000000000;
    ll* tree = constructST(dp, n + 1);
      //  ll l = getMax(tree,n + 1, 1, n);

    for (ll i = 0; i < n; i++)
    {
        ll big = getMax(tree,n + 1, 1, h[i]);
        big = max(big,(ll)0) + c[i];
        updateValue(dp, tree, 0, n, h[i], big, 0);
    }
    ll ans = 0;
    for (ll i = 0; i <= n; i++)
    {
        ans = max(ans, dp[i]);
    }
    cout << ans;

    /*std::cout<<std::fixed;
    std::cout<<std::setprecision(10)<<ans;*/
             //   dp[i][i + 1 + j] = min(dp[i][i + j] + (pre[i + j + 2] - pre[i]),dp[i + 1][i + 1 + j] + (pre[i + j + 2] - pre[i]));

    return 0;
}


Measured memory_bytes: 9088