#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include <cmath>
using namespace std;

typedef long long ll;

ll arr[200005];
int x = 18;
ll st[524287];
int st_n = 200005; 

ll getMid(int s, int e)  
{ 
    return s + (e - s) / 2; 
} 

ll MaxUtil(int ss, int se, int l,  
            int r, int 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 
    int mid = getMid(ss, se); 
      
    return max(MaxUtil(ss, mid, l, r,  
                       2 * node + 1), 
               MaxUtil(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* st, int ss, int se,  
                 int index, ll value, int 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 { 
            int mid = getMid(ss, se); 
              
            if (index >= ss && index <= mid) 
                updateValue(st, ss, mid, index,  
                            value, 2 * node + 1); 
            else
                updateValue(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(int n, int l, int r) 
{ 
    // Check for erroneous input values 
    if (l < 0 || r > n - 1 || l > r)  
    { 
        printf("Invalid Input"); 
        return -1; 
    } 
  
    return MaxUtil(0, n - 1, l, r, 0); 
} 
  
ll constructSTUtil(int ss, int se,  
                    ll* st, int si) 
{ 
    if (ss == se)  
    { 
        st[si] = arr[ss]; 
        return arr[ss]; 
    } 
  
    int mid = getMid(ss, se); 
      
    st[si] = max(constructSTUtil(ss, mid, st,  
                                 si * 2 + 1), 
                 constructSTUtil(mid + 1, se,  
                                 st, si * 2 + 2)); 
      
    return st[si]; 
} 
 
ll n;
ll in;

int main() {
  vector<ll> H, A;
  cin >> n;
  constructSTUtil(0, n-1, st, 0);

  for(int i = 0; i < n; i++) {
    cin >> in;
    H.push_back(in);
  }

  for(int i = 0; i < n; i++) {
    cin >> in;
    A.push_back(in);
  }

  ll h,a;
  ll ans = 0;

  for(int i = 0; i < n; i++) {
    h = H[i]; a = A[i];
    ll end_best = getMax(st_n, 1, h);
    updateValue(st, 0, st_n-1, h, end_best+a, 0);
    ans = max(ans, end_best+a);
  }

  cout << ans << endl;

}



Measured memory_bytes: 9200