Problem p01548 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <cmath>
#include <iostream>
#include <vector>

using namespace std;

double gemC[2234];

template <class E1, class E2>
vector<double> dp(const E1 &a, const E2 &b, int m) {
  vector<double> v(m + 1, -1e9);
  for (int i = 0; i <= m; i++) {
    for (int j = 0; j <= i; j++) {
      v[i] = max(v[i], a[j] + b[i - j]);
    }
  }
  return v;
}

int ceil(int n, int d) { return (n + d - 1) / d; }

int main() {
  int n, m;
  cin >> n >> m;
  double mCk[2234] = {};
  for (int i = 1; i <= m; i++) {
    mCk[i] = mCk[i - 1] + log((m + 1. - i) / i);
  }
  for (int i = m; i >= 0; i--) {
    gemC[i] =
        gemC[i + 1] + exp(mCk[i] + i * log(1 / 3.) + (m - i) * log(2 / 3.));
  }
  int mvdv[3];
  for (int i = 0; i < 3; i++) {
    cin >> mvdv[i];
  }
  int vdv[2234][3];
  for (int i = 0; i < n - 1; i++) {
    for (int j = 0; j < 3; j++) {
      cin >> vdv[i][j];
    }
  }
  double ex[3][2234] = {};
  for (int i = 0; i < 3; i++) {
    ex[i][0] = -1;
    for (int j = 1; j <= m; j++) {
      double h[2234] = {};
      double r[2234] = {};
      for (int k = 0; k < n - 1; k++) {
        int nd = ceil(j * mvdv[i], vdv[k][i]);
        if (nd <= m) {
          h[k] = gemC[nd];
          r[k] = h[k] / (1 - h[k]);
        }
      }
      double a0 = 1;
      double b0 = 1;
      for (int k = 0; k < n - 1; k++) {
        a0 *= 1 - h[k];
        b0 *= h[k];
      }
      double a1 = 0;
      for (int k = 0; k < n - 1; k++) {
        a1 += a0 * r[k]; // h[k]/(1-h[k]);
      }
      double a2 = 0;
      for (int k = 0; k < n - 1; k++) {
        a2 += (a1 - a0 * r[k]) * r[k] / 2;
      }
      int p[] = {5, 3, 2};
      ex[i][j] = (a0 + a1 + a2) * p[i] - b0;
    }
  }
  cout << fixed << (float)dp(dp(ex[0], ex[1], m), ex[2], m)[m] << endl;
}


Error: TLE

Fixed submission:

#include <cmath>
#include <iostream>
#include <vector>

using namespace std;

#define double __float128

double gemC[2234];

template <class E1, class E2>
vector<double> dp(const E1 &a, const E2 &b, int m) {
  vector<double> v(m + 1, -1e9);
  for (int i = 0; i <= m; i++) {
    for (int j = 0; j <= i; j++) {
      v[i] = max(v[i], a[j] + b[i - j]);
    }
  }
  return v;
}

int ceil(int n, int d) { return (n + d - 1) / d; }

int main() {
  int n, m;
  cin >> n >> m;
  double mCk[2234] = {1};
  for (int i = 1; i <= m; i++) {
    mCk[i] = mCk[i - 1] * (m + 1 - i) / i;
  }
  for (int i = m; i >= 0; i--) {
    gemC[i] = gemC[i + 1] + mCk[i] * pow(1. / 3, i) * pow(2. / 3, m - i);
  }
  int mvdv[3];
  for (int i = 0; i < 3; i++) {
    cin >> mvdv[i];
  }
  int vdv[2234][3];
  for (int i = 0; i < n - 1; i++) {
    for (int j = 0; j < 3; j++) {
      cin >> vdv[i][j];
    }
  }
  double ex[3][2234] = {};
  for (int i = 0; i < 3; i++) {
    ex[i][0] = -1;
    for (int j = 1; j <= m; j++) {
      double h[2234] = {};
      double r[2234] = {};
      for (int k = 0; k < n - 1; k++) {
        int nd = ceil(j * mvdv[i], vdv[k][i]);
        if (nd <= m) {
          h[k] = gemC[nd];
          r[k] = h[k] / (1 - h[k]);
        }
      }
      double a0 = 1;
      double b0 = 1;
      for (int k = 0; k < n - 1; k++) {
        a0 *= 1 - h[k];
        b0 *= h[k];
      }
      double a1 = 0;
      for (int k = 0; k < n - 1; k++) {
        a1 += a0 * r[k]; // h[k]/(1-h[k]);
      }
      double a2 = 0;
      for (int k = 0; k < n - 1; k++) {
        a2 += (a1 - a0 * r[k]) * r[k] / 2;
      }
      int p[] = {5, 3, 2};
      ex[i][j] = (a0 + a1 + a2) * p[i] - b0;
    }
  }
  cout << fixed << (float)dp(dp(ex[0], ex[1], m), ex[2], m)[m] << endl;
}