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

#include <algorithm>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>

using namespace std;

int n, m;
string bits[1001];
const int INF = 1000000000;

// bitset<int> nums[1<<11];
map<set<int>, int> sets;
int id;
map<int, int> dp[1 << 11];
// map<set<int>,int > dp[1<<11];

// »ÝgÁ½¿âA»Ì¿âÉæÁÄ¾çê½ªÌ¤¿AÇÌªð©Ä¢é©AÅ»
int dfs(int s, int pos, set<int> &si, int sel) {
  // WÌTCYª1Èº
  if (si.size() <= 1)
    return 0;
  if (s == (1 << m) - 1)
    return INF;
  if (sets.find(si) == sets.end())
    sets[si] = id++;
  if (dp[s].find(sets[si]) != dp[s].end())
    return dp[s][sets[si]];
  int res = INF;
  // ÇÌ¿âðg¤©
  for (int i = 0; i < m; i++) {
    // ·ÅÉgpÏÝ
    if ((s >> i) & 1)
      continue;
    // ªðs¤
    set<int> si1, si2;
    for (set<int>::iterator it = si.begin(); it != si.end(); it++) {
      int idx = *it;
      if (bits[idx][i] == '1')
        si1.insert(idx);
      else
        si2.insert(idx);
    }
    res = min(res,
              max(dfs(s | (1 << i), i, si1, 0), dfs(s | (1 << i), i, si2, 1)) +
                  1);
  }
  return dp[s][sets[si]] = res;
}

int main() {
  while (cin >> m >> n && !(m == 0 && n == 0)) {
    // memset(dp,-1,sizeof(dp));
    for (int i = 0; i < (1 << 11); i++)
      dp[i].clear();
    sets.clear();
    id = 0;
    // for(int i=0;i<(1<<11);i++)
    // nums[i]=i;
    for (int i = 0; i < n; i++)
      cin >> bits[i];
    set<int> init;
    for (int i = 0; i < n; i++)
      init.insert(i);
    int res = INF;
    res = dfs(0, 0, init, 0);
    cout << res << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>

using namespace std;

int n, m;
string bits[1001];
const int INF = 1000000000;
//
// ifstream ifs("input.txt");
// #define cin ifs

int dp[1 << 11][4100];
vector<set<int>> sets[1 << 11];

// »ÝgÁ½¿âA»Ì¿âÉæÁÄ¾çê½ªÌ¤¿AÇÌªð©Ä¢é©AÅ»
int dfs(int s, int pos, set<int> &si) {
  if (dp[s][pos] != -1)
    return dp[s][pos];
  // WÌTCYª1Èº
  if (si.size() <= 1)
    return 0;
  int res = INF;
  // ÇÌ¿âðg¤©
  for (int i = 0; i < m; i++) {
    // ·ÅÉgpÏÝ
    if ((s >> i) & 1)
      continue;
    // ªðs¤
    set<int> si1, si2;
    for (set<int>::iterator it = si.begin(); it != si.end(); it++) {
      int idx = *it;
      if (bits[idx][i] == '1')
        si1.insert(idx);
      else
        si2.insert(idx);
    }
    res = min(res, max(dfs(s | (1 << i), pos * 2 + 1, si1),
                       dfs(s | (1 << i), pos * 2 + 2, si2)) +
                       1);
  }
  return dp[s][pos] = res;
}

// »ÝÌóÔÅìêé·×ÄÌóÔðßÄ¨­
void dfs2(const set<int> &si, int s, int pos) {
  if (pos == m)
    return;
  // sizeª1Èº
  if (si.size() <= 1)
    return;
  set<int> si1, si2;
  int i = pos;
  for (set<int>::iterator it = si.begin(); it != si.end(); it++) {
    int idx = *it;
    if (bits[idx][i] == '1')
      si1.insert(idx);
    else
      si2.insert(idx);
  }
  // ªÂ\\ÈêAªðs¢AWÉÁ¦é
  if (!(si1.size() == 0 || si2.size() == 0)) {
    sets[s | (1 << i)].push_back(si1);
    sets[s | (1 << i)].push_back(si2);
    // »ê¼êWÌTCYªÜ¾2ÈãÅ éêAÄA
    dfs2(si1, s | (1 << i), pos + 1);
    dfs2(si2, s | (1 << i), pos + 1);
  }
  // ¡ñÌ¿âÅÍªµÈ¢
  dfs2(si, s, pos + 1);
}

int main() {
  while (cin >> m >> n && !(m == 0 && n == 0)) {
    memset(dp, -1, sizeof(dp));
    for (int i = 0; i < (1 << 11); i++)
      sets[i].clear();
    for (int i = 0; i < n; i++)
      cin >> bits[i];
    set<int> init;
    for (int i = 0; i < n; i++)
      init.insert(i);
    int res = INF;
    // OÅA»ê¼êÌNGÌgÝí¹Åª³êéWðßÄ¨­
    dfs2(init, 0, 0);
    res = dfs(0, 0, init);
    cout << res << endl;
  }
  return 0;
}