// Original C++ solution (slower):
#include <cstdio>

#include <cmath>

#include <vector>

#include <algorithm>

#include <array>

#include <set>

#include <map>

#include <queue>

#include <tuple>

#include <unordered_set>

#include <unordered_map>

#include <functional>

#include <cassert>

#define repeat(i, n) for (int i = 0; (i) < int(n); ++(i))

#define repeat_from(i, m, n) for (int i = (m); (i) < int(n); ++(i))

#define repeat_reverse(i, n) for (int i = (n)-1; (i) >= 0; --(i))

#define repeat_from_reverse(i, m, n) for (int i = (n)-1; (i) >= int(m); --(i))

#define whole(x) begin(x), end(x)

#define unittest_name_helper(counter) unittest_ ## counter

#define unittest_name(counter) unittest_name_helper(counter)

#define unittest __attribute__((constructor)) void unittest_name(__COUNTER__) ()

using ll = long long;

using namespace std;

template <class T> inline void setmax(T & a, T const & b) { a = max(a, b); }

template <class T> inline void setmin(T & a, T const & b) { a = min(a, b); }

template <typename X, typename T> auto vectors(X x, T a) { return vector<T>(x, a); }

template <typename X, typename Y, typename Z, typename... Zs> auto vectors(X x, Y y, Z z, Zs... zs) { auto cont = vectors(y, z, zs...); return vector<decltype(cont)>(x, cont); }



int main() {

    int n; scanf("%d", &n);

    vector<int> t(n); repeat (i, n) scanf("%d", &t[i]);

    vector<int> v(n); repeat (i, n) scanf("%d", &v[i]);

    const int max_v = *max_element(whole(v));

    constexpr int zoom = 12;

    vector<double> cur(zoom * max_v + 3, - INFINITY);

    vector<double> prv(zoom * max_v + 3, - INFINITY);

    cur[0] = 0;

    repeat (i, n) {

        fill(cur.begin() + (zoom * v[i] + 1), cur.end(), - INFINITY);

        fill(prv.begin() + (zoom * v[i] + 1), prv.end(), - INFINITY);

        repeat (tick, zoom * t[i]) {

            cur.swap(prv);

            cur[0] = max(prv[0], prv[1] + 0.5 / zoom);

            repeat_from (a, 1, zoom * v[i] + 1) {

                cur[a] = max({ prv[a - 1] - 0.5 / zoom, prv[a], prv[a + 1] + 0.5 / zoom }) + a /(double) (zoom * zoom);

            }

        }

    }

    printf("%.12lf\n", cur[0]);

    return 0;

}


// Optimized solution to the same problem (faster):
#include <algorithm>

#include <cmath>

#include <cstdio>

#include <vector>

#define repeat(i, n) for (int i = 0; (i) < int(n); ++(i))

#define repeat_from(i, m, n) for (int i = (m); (i) < int(n); ++(i))

#define whole(x) begin(x), end(x)

using namespace std;



int main() {

    int n; scanf("%d", &n);

    vector<int> t(n); repeat (i, n) scanf("%d", &t[i]);

    vector<int> v(n); repeat (i, n) scanf("%d", &v[i]);

    const int max_v = *max_element(whole(v));

    constexpr int zoom = 2;

    vector<double> cur(zoom * max_v + 3, - INFINITY);

    vector<double> prv(zoom * max_v + 3, - INFINITY);

    cur[0] = 0;

    repeat (i, n) {

        fill(cur.begin() + (zoom * v[i] + 1), cur.end(), - INFINITY);

        fill(prv.begin() + (zoom * v[i] + 1), prv.end(), - INFINITY);

        repeat (tick, zoom * t[i]) {

            cur.swap(prv);

            cur[0] = max(prv[0], prv[1] + 0.5 / zoom);

            repeat_from (a, 1, zoom * v[i] + 1) {

                cur[a] = max({ prv[a - 1] - 0.5 / zoom, prv[a], prv[a + 1] + 0.5 / zoom }) + a /(double) (zoom * zoom);

            }

        }

    }

    printf("%.12lf\n", cur[0]);

    return 0;

}


// Fastest known solution for this problem: