Problem p03169 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bits/stdc++.h>
#include <cmath>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pullull;
typedef pair<ll, int> plli;
typedef pair<int, pii> pipii;
typedef vector<vector<int>> mati;
typedef vector<vector<double>> matd;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;

#define rep(i, x, y) for (int i = (x); i < (y); ++i)

template <typename T> void vec_print(vector<T> VEC) {
  rep(i, 0, VEC.size()) { cout << VEC[i] << " "; }
  cout << "\n";
};

template <typename T>
void mat_print(vector<vector<T>> MAT){
    rep(i, 0, MAT.size()){rep(j, 0, MAT[i].size()){cout << MAT[i][j] << " ";
}
cout << "\n";
}
}
;

template <typename CLASS1, typename CLASS2> class HOGE {
public:
  CLASS1 key;
  CLASS2 value;
  HOGE(ll key, ll value) {
    this->key = index;
    this->value = value;
  };
  ~HOGE(void) { return; };

  void print(void) {
    cout << "key : " << key << ", value : " << value << "\n";
    return;
  };

  bool operator==(const HOGE &obj) { return (this->value == obj.value); };
  bool operator<(const HOGE &obj) { return (this->value < obj.value); };
  bool operator>(const HOGE &obj) { return (this->value > obj.value); };
};

constexpr int INF = (1 << 30);
constexpr ll INFLL = 1LL << 62;
constexpr long double EPS = 1e-12;

double exp_value(ll D1, ll D2, ll D3, ll N,
                 vector<vector<vector<double>>> &dp) {
  if (D1 < 0 || D2 < 0 || D3 < 0)
    return (double)0.0;
  if (D1 == 0 && D2 == 0 && D3 == 0)
    return (double)0.0;
  if (dp[D1][D2][D3] >= -0.5)
    return dp[D1][D2][D3];
  /*
  exp_value(D1, D2, D3, N, dp)
  = (N-D1-D2-D3)*exp_value(D1, D2, D3, N, dp)/N
  + D1*exp_value(D1-1, D2, D3, N, dp)/N
  + D2*exp_value(D1+1, D2-1, D3, N, dp)/N
  + D3*exp_value(D1, D2+1, D3-1, N, dp)/N
  + 1
  */
  ll sum = D1 + D2 + D3;
  double tmp1 = (double)D1 * exp_value(D1 - 1, D2, D3, N, dp) / sum;
  double tmp2 = (double)D2 * exp_value(D1 + 1, D2 - 1, D3, N, dp) / sum;
  double tmp3 = (double)D3 * exp_value(D1, D2 + 1, D3 - 1, N, dp) / sum;
  return dp[D1][D2][D3] = tmp1 + tmp2 + tmp3 + (double)N / sum;
}

int main() {
  cin.tie(0); // cut the cin and cout (default, std::flush is performed after
              // std::cin)
  ios::sync_with_stdio(
      false); // cut the iostream and stdio (DON'T endl; BUT "\n";)

  ll N;
  cin >> N;
  vll Dishes(4, 0);
  ll a;
  rep(i, 0, N) {
    cin >> a;
    ++Dishes[a];
  }
  vector<vector<vector<double>>> dp(
      300, vector<vector<double>>(300, vector<double>(300, -1.0)));

  printf("%.10lf\n", exp_value(Dishes[1], Dishes[2], Dishes[3], N, dp));

  return 0;
}

Fixed submission:
#include <algorithm>
#include <bits/stdc++.h>
#include <cmath>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pullull;
typedef pair<ll, int> plli;
typedef pair<int, pii> pipii;
typedef vector<vector<int>> mati;
typedef vector<vector<double>> matd;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;

#define rep(i, x, y) for (int i = (x); i < (y); ++i)

template <typename T> void vec_print(vector<T> VEC) {
  rep(i, 0, VEC.size()) { cout << VEC[i] << " "; }
  cout << "\n";
};

template <typename T>
void mat_print(vector<vector<T>> MAT){
    rep(i, 0, MAT.size()){rep(j, 0, MAT[i].size()){cout << MAT[i][j] << " ";
}
cout << "\n";
}
}
;

template <typename CLASS1, typename CLASS2> class HOGE {
public:
  CLASS1 key;
  CLASS2 value;
  HOGE(ll key, ll value) {
    this->key = index;
    this->value = value;
  };
  ~HOGE(void) { return; };

  void print(void) {
    cout << "key : " << key << ", value : " << value << "\n";
    return;
  };

  bool operator==(const HOGE &obj) { return (this->value == obj.value); };
  bool operator<(const HOGE &obj) { return (this->value < obj.value); };
  bool operator>(const HOGE &obj) { return (this->value > obj.value); };
};

constexpr int INF = (1 << 30);
constexpr ll INFLL = 1LL << 62;
constexpr long double EPS = 1e-12;

double exp_value(ll D1, ll D2, ll D3, ll N,
                 vector<vector<vector<double>>> &dp) {
  if (D1 < 0 || D2 < 0 || D3 < 0)
    return (double)0.0;
  if (D1 == 0 && D2 == 0 && D3 == 0)
    return (double)0.0;
  if (dp[D1][D2][D3] >= -0.5)
    return dp[D1][D2][D3];
  /*
  exp_value(D1, D2, D3, N, dp)
  = (N-D1-D2-D3)*exp_value(D1, D2, D3, N, dp)/N
  + D1*exp_value(D1-1, D2, D3, N, dp)/N
  + D2*exp_value(D1+1, D2-1, D3, N, dp)/N
  + D3*exp_value(D1, D2+1, D3-1, N, dp)/N
  + 1
  */
  ll sum = D1 + D2 + D3;
  double tmp1 = (double)D1 * exp_value(D1 - 1, D2, D3, N, dp) / sum;
  double tmp2 = (double)D2 * exp_value(D1 + 1, D2 - 1, D3, N, dp) / sum;
  double tmp3 = (double)D3 * exp_value(D1, D2 + 1, D3 - 1, N, dp) / sum;
  return dp[D1][D2][D3] = tmp1 + tmp2 + tmp3 + (double)N / sum;
}

int main() {
  cin.tie(0); // cut the cin and cout (default, std::flush is performed after
              // std::cin)
  ios::sync_with_stdio(
      false); // cut the iostream and stdio (DON'T endl; BUT "\n";)

  ll N;
  cin >> N;
  vll Dishes(4, 0);
  ll a;
  rep(i, 0, N) {
    cin >> a;
    ++Dishes[a];
  }
  vector<vector<vector<double>>> dp(
      Dishes[1] + Dishes[2] + Dishes[3] + 1,
      vector<vector<double>>(Dishes[2] + Dishes[3] + 1,
                             vector<double>(Dishes[3] + 1, -1.0)));

  printf("%.10lf\n", exp_value(Dishes[1], Dishes[2], Dishes[3], N, dp));

  return 0;
}