#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
struct Bipartite_Matching {
  vector<vector<int> > graph;
  vector<int> match, alive, used;
  int timestamp;
  Bipartite_Matching(int n) {
    timestamp = 0;
    graph.resize(n);
    alive.assign(n, 1);
    used.assign(n, 0);
    match.assign(n, -1);
  }
  void add_edge(int u, int v) {
    graph[u].push_back(v);
    graph[v].push_back(u);
  }
  bool dfs(int v) {
    used[v] = timestamp;
    for (int i = 0; i < graph[v].size(); i++) {
      int u = graph[v][i], w = match[u];
      if (alive[u] == 0) continue;
      if (w == -1 || (used[w] != timestamp && dfs(w))) {
        match[v] = u;
        match[u] = v;
        return (true);
      }
    }
    return (false);
  }
  int bipartite_matching() {
    int ret = 0;
    for (int i = 0; i < graph.size(); i++) {
      if (alive[i] == 0) continue;
      if (match[i] == -1) {
        ++timestamp;
        ret += dfs(i);
      }
    }
    return (ret);
  }
};
double dp[51][51][51][51];
bool memo[51][51][51][51];
int main() {
  int N, A[51], B[51];
  cin >> N;
  vector<pair<int, int> > vs(N);
  for (int i = 0; i < N; i++) cin >> vs[i].first;
  for (int i = 0; i < N; i++) cin >> vs[i].second;
  sort(begin(vs), end(vs));
  reverse(begin(vs), end(vs));
  for (int i = 0; i < N; i++) tie(A[i], B[i]) = vs[i];
  A[N] = -1;
  double low = 0, high = 1000000000;
  auto check = [&](double v) {
    vector<double> C(N);
    for (int i = 0; i < N; i++) {
      C[i] = A[i] - B[i] * v;
    }
    memset(memo, false, sizeof(memo));
    function<double(int, int, int, int)> rec = [&](int idx, int first,
                                                   int firstsame, int last) {
      if (idx == N) return 0.0;
      if (memo[idx][first][firstsame][last])
        return dp[idx][first][firstsame][last];
      memo[idx][first][firstsame][last] = true;
      double ret = 1e9;
      if (first > last) {
        if (A[idx] != A[idx + 1])
          ret = min(ret, rec(idx + 1, first + firstsame, 0, last + 1));
        else
          ret = min(ret, rec(idx + 1, first, firstsame, last + 1));
      }
      if (A[idx] != A[idx + 1])
        ret = min(ret, rec(idx + 1, first + firstsame + 1, 0, last) + C[idx]);
      else
        ret = min(ret, rec(idx + 1, first, firstsame + 1, last) + C[idx]);
      return dp[idx][first][firstsame][last] = ret;
    };
    return rec(0, 0, 0, 0) <= 0;
  };
  for (int i = 0; i < 100; i++) {
    double mid = (low + high) / 2;
    if (check(mid))
      high = mid;
    else
      low = mid;
  }
  cout << (int64)(high * 1000 + 0.5) << endl;
}
