Problem p03169 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cctype>
#include <chrono>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define rep(i, p, q) for (ll i = p; i < q; i++)
#define ll long long

using namespace std;

const long long MAX_N = 1 << 17;

long long dat[2 * MAX_N - 1];

ll ecd(ll a, ll b) {
  if (a < b)
    swap(a, b);
  if (b == 0)
    return a;
  else {
    return ecd(b, a % b);
  }
}

ll pow(ll a, ll b) {
  vector<ll> d = vector<ll>((ll)(log(b)) + 2);
  d[0] = a;
  rep(i, 1, d.size()) d[i] = d[i - 1] * d[i - 1];
  ll ret = 1;
  rep(i, 0, log(b) + 1) {
    if (b & 1 << i)
      ret *= d[i];
  }
  return ret;
}

// J
vector<vector<vector<long double>>> dp;
ll n;
ll s1, s2, s3;

long double rec(ll i, ll j, ll k) {
  if (dp[i][j][k] >= 0)
    return dp[i][j][k];

  if (i == 0 && j == 0 && k == 0)
    return 0.0;

  long double res = 0;
  if (i > 0)
    res += rec(i - 1, j, k) * i;
  if (j > 0)
    res += rec(i + 1, j - 1, k) * j;
  if (k > 0)
    res += rec(i, j + 1, k - 1) * k;
  res += n;
  res *= 1.0 / (long double)(i + j + k);

  return dp[i][j][k] = res;
}

int main(void) {
  n;
  cin >> n;
  s1 = 0, s2 = 0, s3 = 0;
  rep(i, 0, n) {
    ll sushi;
    cin >> sushi;
    if (sushi == 1)
      s1++;
    else if (sushi == 2)
      s2++;
    else
      s3++;
  }
  dp = vector<vector<vector<long double>>>(
      s1 + 2,
      vector<vector<long double>>(s2 + 2, vector<long double>(s3 + 2, -1)));
  cout << rec(s1, s2, s3) << endl;
}

Fixed submission:
#include <algorithm>
#include <cctype>
#include <chrono>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define rep(i, p, q) for (ll i = p; i < q; i++)
#define ll long long

using namespace std;

const long long MAX_N = 1 << 17;

long long dat[2 * MAX_N - 1];

ll ecd(ll a, ll b) {
  if (a < b)
    swap(a, b);
  if (b == 0)
    return a;
  else {
    return ecd(b, a % b);
  }
}

ll pow(ll a, ll b) {
  vector<ll> d = vector<ll>((ll)(log(b)) + 2);
  d[0] = a;
  rep(i, 1, d.size()) d[i] = d[i - 1] * d[i - 1];
  ll ret = 1;
  rep(i, 0, log(b) + 1) {
    if (b & 1 << i)
      ret *= d[i];
  }
  return ret;
}

// J
vector<vector<vector<long double>>> dp;
ll n;
ll s1, s2, s3;

long double rec(ll i, ll j, ll k) {
  if (dp[i][j][k] >= 0)
    return dp[i][j][k];

  if (i == 0 && j == 0 && k == 0)
    return 0.0;

  long double res = 0;
  if (i > 0)
    res += rec(i - 1, j, k) * i;
  if (j > 0)
    res += rec(i + 1, j - 1, k) * j;
  if (k > 0)
    res += rec(i, j + 1, k - 1) * k;
  res += n;
  res *= 1.0 / (long double)(i + j + k);

  return dp[i][j][k] = res;
}

int main(void) {
  n;
  cin >> n;
  s1 = 0, s2 = 0, s3 = 0;
  rep(i, 0, n) {
    ll sushi;
    cin >> sushi;
    if (sushi == 1)
      s1++;
    else if (sushi == 2)
      s2++;
    else
      s3++;
  }
  dp = vector<vector<vector<long double>>>(
      310, vector<vector<long double>>(310, vector<long double>(310, -1)));
  cout << setprecision(10) << rec(s1, s2, s3) << endl;
}