Problem p01354 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

int POW[17], M, N;
double dp[65536][16];
double table[16][16];

double dfs(int state, int enemy) {

  if (enemy == N)
    return 1.0;
  if (state == 0)
    return 0.0;

  if (dp[state][enemy] >= 0.0)
    return dp[state][enemy];

  double maximum = 0.0;

  for (int cat = 0; cat < M; cat++) {
    if (!(state & (1 << cat)))
      continue;

    double sum = 0.0, prob = 1.0;
    int next_state = state - POW[cat];

    for (int i = enemy; i < N; i++) {
      sum += dfs(next_state, i) * prob * (1.0 - table[cat][i]);
      prob *= table[cat][i];
    }
    sum += prob;

    maximum = max(maximum, sum);
  }

  return dp[state][enemy] = maximum;
}

int main() {

  for (int i = 0; i <= 16; i++)
    POW[i] = pow(2, i);

  scanf("%d %d", &M, &N);

  for (int i = 0; i < M; i++) {
    for (int k = 0; k < N; k++)
      scanf("%lf", &table[i][k]);
  }

  int limit = POW[M];

  for (int i = 0; i < limit; i++) {
    for (int k = 0; k < N; k++) {
      dp[i][k] = -1.0;
    }
  }

  printf("%.12lf\\n", dfs(limit - 1, 0));

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

int POW[17], M, N;
float dp[65536][16][16];
float table[16][16];

int main() {

  for (int i = 0; i <= 16; i++)
    POW[i] = pow(2, i);

  scanf("%d %d", &M, &N);

  for (int i = 0; i < M; i++) {
    for (int k = 0; k < N; k++)
      scanf("%f", &table[i][k]);
  }

  int limit = POW[M];

  for (int i = 0; i < limit; i++) {
    for (int k = 0; k < N; k++) {
      for (int p = 0; p < M; p++)
        dp[i][k][p] = -1.0;
    }
  }

  int next_cat[M]; //?¬???????????????????????£?
  int next_num, next_state;

  float maximum;

  //?????????????????????????¢???????????????????????¨????????????????
  for (int state = 0; state < limit; state++) {

    next_num = 0;
    //?¬????????????????????????????????¨????????????????
    for (int cat = 0; cat < M; cat++) { //???????????????
      if (state & (1 << cat)) {         //???????????£???????????´???
        next_cat[next_num++] = cat;
      }
    }

    for (int cat = 0; cat < M; cat++) {

      if (state & (1 << cat)) {

        next_state = state - POW[cat];

        if (next_state == 0) { //??????????????§????????´???
          dp[state][N - 1][cat] = table[cat][N - 1];
        } else { //?????????????????????????????´???

          //?¬??????????????????¢???
          maximum = 0.0;
          for (int i = 0; i < next_num; i++) {
            if (dp[next_state][N - 1][next_cat[i]] > maximum) {
              maximum = dp[next_state][N - 1][next_cat[i]];
            }
          }
          dp[state][N - 1][cat] =
              table[cat][N - 1] +
              (1.0 - table[cat][N - 1]) *
                  maximum; //????????????????¢????+????????????????????????????°?????????¨???1?????????????????????????¢????
        }
      }
    }
  }

  for (int enemy = N - 2; enemy >= 0; enemy--) {
    for (int state = 0; state < limit; state++) {

      next_num = 0;
      //?¬????????????????????????????????¨????????????????
      for (int cat = 0; cat < M; cat++) { //???????????????
        if (state & (1 << cat)) {         //???????????£???????????´???
          next_cat[next_num++] = cat;
        }
      }

      for (int cat = 0; cat < M; cat++) {

        if (state & (1 << cat)) {

          next_state = state - POW[cat];

          if (next_state == 0) { //??????????????§????????´???
            dp[state][enemy][cat] =
                max(dp[state][enemy][cat],
                    dp[state][enemy + 1][cat] * table[cat][enemy]);
          } else { //?????????????????????????????´???

            //?¬??????????????????¢???
            maximum = 0.0;
            for (int i = 0; i < next_num; i++) {
              if (dp[next_state][enemy][next_cat[i]] > maximum) {
                maximum = dp[next_state][enemy][next_cat[i]];
              }
            }
            if (dp[state][enemy][cat] <
                table[cat][enemy] * dp[state][enemy + 1][cat] +
                    (1.0 - table[cat][enemy]) * maximum) {
              dp[state][enemy][cat] =
                  table[cat][enemy] * dp[state][enemy + 1][cat] +
                  (1.0 - table[cat][enemy]) * maximum;
            }
          }
        }
      }
    }
  }

  float ans = 0.0;

  for (int i = 0; i < M; i++) {
    if (ans < dp[limit - 1][0][i]) {
      ans = dp[limit - 1][0][i];
    }
  }

  printf("%.6f\\n", ans);

  return 0;
}