#include <bits/stdc++.h>
#pragma GCC optimize("03")
using namespace std;
const int mn = 2e4 + 7;
int n1, n = 1, i, x, app[mn];
long long ans;
pair<int, int> mini[mn];
void update(int v) { mini[v] = min(mini[v * 2], mini[v * 2 + 1]); }
void push(int v) {
  app[v * 2] += app[v];
  app[v * 2 + 1] += app[v];
  mini[v * 2].first += app[v];
  mini[v * 2 + 1].first += app[v];
  app[v] = 0;
}
void make_tree(int v, int tl, int tr) {
  if (tl == tr) return;
  int m = (tl + tr) / 2;
  make_tree(v * 2, tl, m);
  make_tree(v * 2 + 1, m + 1, tr);
  update(v);
}
pair<int, int> get_min(int v, int tl, int tr, int l, int r) {
  if (l > r) return {1e9 + 7, 1e9 + 7};
  if (tl == l && tr == r) return mini[v];
  push(v);
  int m = (tl + tr) / 2;
  pair<int, int> x1, x2;
  x1 = get_min(v * 2, tl, m, l, min(m, r));
  x2 = get_min(v * 2 + 1, m + 1, tr, max(m + 1, l), r);
  return min(x1, x2);
}
void add(int v, int tl, int tr, int l, int r, int x) {
  if (l > r) return;
  if (tl == l && tr == r) {
    app[v] += x;
    mini[v].first += x;
    return;
  }
  push(v);
  int m = (tl + tr) / 2;
  add(v * 2, tl, m, l, min(m, r), x);
  add(v * 2 + 1, m + 1, tr, max(m + 1, l), r, x);
  update(v);
}
int rec(int l, int r) {
  if (l > r) return 0;
  pair<int, int> g = get_min(1, 1, n, l, r);
  add(1, 1, n, l, r, -g.first);
  return min(r - l + 1, rec(l, g.second - 1) + rec(g.second + 1, r) + g.first);
}
signed main() {
  iostream::sync_with_stdio(0);
  cin.tie(0);
  cin >> n1;
  while (n < n1) n *= 2;
  for (i = n; i < n + n1; i++) {
    cin >> x;
    mini[i] = {x, i - n + 1};
  }
  for (i = n + n1; i < 2 * n; i++) mini[i] = {1e9 + 7, i - n + 1};
  make_tree(1, 1, n);
  cout << rec(1, n1);
  return 0;
}
