#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void ckmax(T& x, T y) {
  x = (y > x ? y : x);
}
template <typename T>
inline void ckmin(T& x, T y) {
  x = (y < x ? y : x);
}
const int MAXN = 80, MAXOP = MAXN * (MAXN - 1) / 2;
const int INF = 0x3f3f3f3f;
int n, a[MAXN + 5], cnt[2], pos[MAXN + 5];
int total, max_op;
int dp[MAXOP + 5][MAXN + 5][MAXN + 5];
struct Queue {
  int a[MAXN + 5];
  int ql, qr;
  int size() { return qr - ql + 1; }
  bool empty() { return ql > qr; }
  int front() { return a[ql]; }
  int back() { return a[qr]; }
  int back2() { return a[qr - 1]; }
  void push_back(int e) { a[++qr] = e; }
  void pop_back() { --qr; }
  void init() {
    ql = 1;
    qr = 0;
  }
} que[MAXOP + 5][MAXN + 5];
int ans[MAXOP + 5];
int calc(int len) { return len * (len - 1) / 2; }
int calc2(int len) { return len * (len - 1); }
int main() {
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    cin >> a[i];
    cnt[a[i]]++;
    if (a[i] == 1) {
      pos[cnt[1]] = i;
    }
  }
  total = calc(cnt[0]);
  max_op = calc(n);
  if (!cnt[1]) {
    for (int i = 0; i <= max_op; ++i) cout << 0 << " ";
    cout << endl;
    return 0;
  }
  memset(dp, 0x3f, sizeof(dp));
  for (int j = 0; j <= max_op; ++j) {
    for (int k = 1; k <= cnt[1]; ++k) {
      que[j][k].init();
    }
  }
  for (int i = 1; i <= n; ++i) {
    dp[abs(pos[1] - i)][1][i] = calc2(i - 1);
    while (
        que[abs(pos[1] - i)][1].size() >= 2 &&
        ((dp[abs(pos[1] - i)][1][(que[abs(pos[1] - i)][1].back())] +
          (que[abs(pos[1] - i)][1].back()) * (que[abs(pos[1] - i)][1].back()) +
          3 * (que[abs(pos[1] - i)][1].back())) -
         (dp[abs(pos[1] - i)][1][(que[abs(pos[1] - i)][1].back2())] +
          (que[abs(pos[1] - i)][1].back2()) *
              (que[abs(pos[1] - i)][1].back2()) +
          3 * (que[abs(pos[1] - i)][1].back2()))) *
                (i - que[abs(pos[1] - i)][1].back()) >
            ((dp[abs(pos[1] - i)][1][(i)] + (i) * (i) + 3 * (i)) -
             (dp[abs(pos[1] - i)][1][(que[abs(pos[1] - i)][1].back())] +
              (que[abs(pos[1] - i)][1].back()) *
                  (que[abs(pos[1] - i)][1].back()) +
              3 * (que[abs(pos[1] - i)][1].back()))) *
                (que[abs(pos[1] - i)][1].back() -
                 que[abs(pos[1] - i)][1].back2()))
      que[abs(pos[1] - i)][1].pop_back();
    que[abs(pos[1] - i)][1].push_back(i);
  }
  for (int j = 0; j <= max_op; ++j) {
    for (int k = 2; k <= cnt[1]; ++k) {
      for (int i = k; i <= n - (cnt[1] - k); ++i) {
        if (j < abs(pos[k] - i)) continue;
        int last_j = j - abs(pos[k] - i);
        if (que[last_j][k - 1].empty()) continue;
        if (que[last_j][k - 1].front() >= i) continue;
        int l = que[last_j][k - 1].ql;
        int r = que[last_j][k - 1].qr;
        while (l < r) {
          int mid = (l + r + 1) >> 1;
          if (que[last_j][k - 1].a[mid] < i) {
            l = mid;
          } else {
            r = mid - 1;
          }
        }
        l = que[last_j][k - 1].ql;
        while (l < r) {
          int mid = (l + r) >> 1;
          int p1 = que[last_j][k - 1].a[mid],
              p2 = que[last_j][k - 1].a[mid + 1];
          if ((dp[last_j][k - 1][(p2)] + (p2) * (p2) + 3 * (p2)) -
                  (dp[last_j][k - 1][(p1)] + (p1) * (p1) + 3 * (p1)) >
              2 * i * (p2 - p1)) {
            r = mid;
          } else {
            l = mid + 1;
          }
        }
        ckmin(dp[j][k][i], dp[last_j][k - 1][que[last_j][k - 1].a[l]] +
                               calc2(i - que[last_j][k - 1].a[l] - 1));
        while (que[j][k].size() >= 2 &&
               ((dp[j][k][(que[j][k].back())] +
                 (que[j][k].back()) * (que[j][k].back()) +
                 3 * (que[j][k].back())) -
                (dp[j][k][(que[j][k].back2())] +
                 (que[j][k].back2()) * (que[j][k].back2()) +
                 3 * (que[j][k].back2()))) *
                       (i - que[j][k].back()) >
                   ((dp[j][k][(i)] + (i) * (i) + 3 * (i)) -
                    (dp[j][k][(que[j][k].back())] +
                     (que[j][k].back()) * (que[j][k].back()) +
                     3 * (que[j][k].back()))) *
                       (que[j][k].back() - que[j][k].back2()))
          que[j][k].pop_back();
        que[j][k].push_back(i);
      }
    }
  }
  int res = total;
  for (int j = 0; j <= max_op; ++j) {
    for (int i = cnt[1]; i <= n; ++i)
      if (dp[j][cnt[1]][i] != INF) {
        ckmin(res, (dp[j][cnt[1]][i] + calc2(n - i)) / 2);
      }
    cout << total - res << " ";
  }
  cout << endl;
  return 0;
}
