#include "omp.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <random>
#include <bitset>
#include <unordered_set>
#include <cassert>
#include <list>


using namespace std;

typedef long long ll;
typedef long double ld;


const int sze = 50, M = 5e3 + 1, psze = 15;
const ll INF = 6e12 + 10;


ll dp[2][M][sze][sze];


signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	int n;
	cin >> n;
	vector<pair<int, int>> challengers(n);
	vector<int> pref(n);

	for (int i = 0; i < n; ++i)
		cin >> challengers[i].first;

	for (int i = 0; i < n; ++i)
		cin >> challengers[i].second;

	sort(challengers.begin(), challengers.end());


	pref[0] = challengers[0].second;
	for (int i = 1; i < n; ++i)
		pref[i] = pref[i - 1] + challengers[i].second;


	for (int i = 0; i <= n; ++i)
		for (int j = 0; j <= pref[n - 1]; ++j)
			for (int z = 0; z <= n; ++z)
				for (int cur = 0; cur <= 1; ++cur)
					dp[cur][j][z][i] = INF;//LL

	challengers.push_back({ 0, 0 });

	int cur = 0;
	for (int t = 0; t < n; ++t)
	{
		if (challengers[t + 1].first != challengers[t].first && (!t || challengers[t].first != challengers[t - 1].first))
		{
			for (int j = 0; j <= pref[n - 1]; ++j)
				for (int z = 0; z <= n; ++z)
				{
					if (dp[cur][j][z][0] == INF)
						continue;

					int to1 = dp[cur ^ 1][j + challengers[t].second][max(0, z - 1)][0] = min(dp[cur ^ 1][j + challengers[t].second][max(0, z - 1)][0], dp[cur][j][z][0] + challengers[t].first);
					int to2 = dp[cur ^ 1][j][z + 1][0] = min(dp[cur ^ 1][j][z + 1][0], dp[cur][j][z][0]);
				}

			int to = dp[cur ^ 1][challengers[t].second][max(0, t - 1)][0] = min(dp[cur ^ 1][challengers[t].second][max(0, t - 1)][0], ll(challengers[t].first));

			for (int j = 0; j <= pref[n - 1]; ++j)
				for (int z = 0; z <= n; ++z)
					dp[cur][j][z][0] = INF;

			cur ^= 1;
		}
		else
		{

			for (int j = 0; j <= pref[n - 1]; ++j)
				for (int z = 0; z <= n; ++z)
					for (int k = 0; k <= n; ++k)
					{

						if (dp[cur][j][z][k] == INF)	
							continue;

						int to1 = dp[cur ^ 1][j + challengers[t].second][max(0, z - 1)][k] = min(dp[cur ^ 1][j + challengers[t].second][max(0, z - 1)][k], dp[cur][j][z][k] + challengers[t].first);
						int to2 = dp[cur ^ 1][j][z][k + 1] = min(dp[cur ^ 1][j][z][k + 1], dp[cur][j][z][k]);
						int a = 1;
					}

			int prev = t;
			while (prev >= 0 && challengers[prev].first == challengers[t].first)
				prev--;

			int to = dp[cur ^ 1][challengers[t].second][prev + 1][max(0, t - prev - 2)] = min(dp[cur ^ 1][challengers[t].second][prev + 1][max(0, t - prev - 2)], ll(challengers[t].first));

			for (int j = 0; j <= pref[n - 1]; ++j)
				for (int z = 0; z <= n; ++z)
					for (int k = 0; k <= n; ++k)
						dp[cur][j][z][k] = INF;

			cur ^= 1;

			if (challengers[t + 1].first != challengers[t].first)
			{
				for (int j = 0; j <= pref[n - 1]; ++j)
					for (int z = 0; z <= n; ++z)
						for (int k = 1; k <= n; ++k)
							if (dp[cur][j][z][k] != INF)
							{
								int to1 = dp[cur][j][z + k][0] = min(dp[cur][j][z + k][0], dp[cur][j][z][k]);
								dp[cur][j][z][k] = INF;
								int a = 1;
							}
			}
		}
	}

	ll ans = INF;

	for (int j = 1; j <= pref[n - 1]; ++j)
		for (int cur = 0; cur <= 1; ++cur)
			if (dp[cur][j][0][0] != INF)
				ans = min(ans, (1000LL * dp[cur][j][0][0] + j - 1) / j);

	cout << ans;

	return 0;
}