Problem p03168 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long lli;
typedef long double lld;
#define mod 1000000007
#define mod2 998244353
#define fori(n) for (int i = 0; i < n; i++)
#define forj(n) for (int j = 0; j < n; j++)
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define fast ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define endl "\n"
#define sortvec(a) sort(a.begin(), a.end())
#define watch(x) cerr << "\n" << (#x) << " is " << (x) << endl
#define cerr                                                                   \
  if (true)                                                                    \
  cerr
void print() { cout << endl; }
template <typename T, typename... Args> void print(T a, Args... args) {
  cout << a << " ";
  print(args...);
}
lli llipowerp(lli x, lli y, lli p = LLONG_MAX) {
  lli res = 1;
  x = x % p;
  while (y > 0) {
    if (y & 1)
      res = (res * x) % p;
    y = y >> 1;
    x = (x * x) % p;
  }
  return res;
}
lli binarySearch(vector<int> arr, int l, int r, int x) {
  if (r >= l) {
    lli mid = l + (r - l) / 2;
    if (arr[mid] == x)
      return mid;
    if (arr[mid] > x)
      return binarySearch(arr, l, mid - 1, x);
    return binarySearch(arr, mid + 1, r, x);
  }
  return -1;
}
template <typename T> inline void printvec(vector<T> inp) {
  for (auto it : inp)
    cout << it << " ";
  cout << endl;
}
//---------------------------------------------------------------------------------
int n;
lld dp[3010][3010];
vector<lld> p(1010);

lld fill(int i, int j) {
  if (i + j > n)
    return 0;

  if (i < 0 || j < 0)
    return 0;
  if (dp[i][j] != -1)
    return dp[i][j];

  dp[i][j] = fill(i - 1, j) * p[i + j] + fill(i, j - 1) * (1 - p[i + j]);
  return dp[i][j];
}

int main() {
  cin >> n;
  fori(n + 1) { forj(n + 1) dp[i][j] = -1; }
  fori(n) cin >> p[i + 1];
  dp[0][0] = 1;
  lld ans = 0;

  for (int tails = 0; tails <= n; tails++) {
    if (n - tails > tails)
      ans += fill(n - tails, tails);
  }
  cout << fixed << setprecision(12) << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long lli;
typedef long double lld;
#define mod 1000000007
#define mod2 998244353
#define fori(n) for (int i = 0; i < n; i++)
#define forj(n) for (int j = 0; j < n; j++)
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define fast ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define endl "\n"
#define sortvec(a) sort(a.begin(), a.end())
#define watch(x) cerr << "\n" << (#x) << " is " << (x) << endl
#define cerr                                                                   \
  if (true)                                                                    \
  cerr
void print() { cout << endl; }
template <typename T, typename... Args> void print(T a, Args... args) {
  cout << a << " ";
  print(args...);
}
lli llipowerp(lli x, lli y, lli p = LLONG_MAX) {
  lli res = 1;
  x = x % p;
  while (y > 0) {
    if (y & 1)
      res = (res * x) % p;
    y = y >> 1;
    x = (x * x) % p;
  }
  return res;
}
lli binarySearch(vector<int> arr, int l, int r, int x) {
  if (r >= l) {
    lli mid = l + (r - l) / 2;
    if (arr[mid] == x)
      return mid;
    if (arr[mid] > x)
      return binarySearch(arr, l, mid - 1, x);
    return binarySearch(arr, mid + 1, r, x);
  }
  return -1;
}
template <typename T> inline void printvec(vector<T> inp) {
  for (auto it : inp)
    cout << it << " ";
  cout << endl;
}
//---------------------------------------------------------------------------------
int n;
lld dp[3010][3010];
vector<lld> p(3010);

lld fill(int i, int j) {
  if (i + j > n)
    return 0;

  if (i < 0 || j < 0)
    return 0;
  if (dp[i][j] != -1)
    return dp[i][j];

  dp[i][j] = fill(i - 1, j) * p[i + j] + fill(i, j - 1) * (1 - p[i + j]);
  return dp[i][j];
}

int main() {
  cin >> n;
  fori(n + 1) { forj(n + 1) dp[i][j] = -1; }
  fori(n) cin >> p[i + 1];
  dp[0][0] = 1;
  lld ans = 0;

  for (int tails = 0; tails <= n; tails++) {
    if (n - tails > tails)
      ans += fill(n - tails, tails);
  }
  cout << fixed << setprecision(12) << ans << endl;
}