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

#include <bits/stdc++.h>
using namespace std;

typedef pair<char, char> Pi;   // 2個
typedef pair<Pi, Pi> Pii;      // 4個
typedef pair<Pii, Pii> Piii;   // 8個
typedef pair<Piii, int> Piiii; // 9個

int n;
vector<char> barabara(10);
map<Piiii, char> dp;

vector<vector<char>> mask;

char manzyu(vector<char> &mans) {
  if (dp.find(Piiii(Piii(Pii(Pi(mans[1], mans[2]), Pi(mans[3], mans[4])),
                         Pii(Pi(mans[5], mans[6]), Pi(mans[7], mans[8]))),
                    mans[9])) != dp.end())
    return (dp[Piiii(Piii(Pii(Pi(mans[1], mans[2]), Pi(mans[3], mans[4])),
                          Pii(Pi(mans[5], mans[6]), Pi(mans[7], mans[8]))),
                     mans[9])]);
  char ret = 0;
  for (int i = 0; i < mask.size(); i++) {
    if (mans[1] >= mask[i][1] && mans[2] >= mask[i][2] &&
        mans[3] >= mask[i][3] && mans[4] >= mask[i][4] &&
        mans[5] >= mask[i][5] && mans[6] >= mask[i][6] &&
        mans[7] >= mask[i][7] && mans[8] >= mask[i][8] &&
        mans[9] >= mask[i][9]) {
      for (int j = 1; j < 10; j++) {
        mans[j] -= mask[i][j];
      }
      ret = max(ret, (char)(manzyu(mans) + 1));
      for (int j = 1; j < 10; j++) {
        mans[j] += mask[i][j];
      }
    }
  }
  return (dp[Piiii(Piii(Pii(Pi(mans[1], mans[2]), Pi(mans[3], mans[4])),
                        Pii(Pi(mans[5], mans[6]), Pi(mans[7], mans[8]))),
                   mans[9])] = ret);
}

void isten(vector<char> &ret, int digit, int sum) {
  if (digit <= 0 || sum > 10) {
    return;
  } else if (sum == 10) {
    mask.push_back(ret);
    return;
  } else {
    isten(ret, digit - 1, sum);
    ret[digit]++;
    isten(ret, digit, sum + digit);
    ret[digit]--;
  }
}

int main() {
  vector<char> buff(10, 0);
  isten(buff, 9, 0);

  while (cin >> n, n) {
    for (int i = 1; i < 10; i++)
      barabara[i] = 0;
    dp.clear();
    for (int i = 0; i < n; i++) {
      int m;
      cin >> m;
      barabara[m]++;
    }

    int prad = 0;
    for (int i = 1; i <= 4; i++) {
      int cost = min(barabara[i], barabara[10 - i]);
      prad += cost;
      barabara[i] -= cost;
      barabara[10 - i] -= cost;
    }
    prad += barabara[5] / 2;
    barabara[5] -= barabara[5] / 2 * 2;

    cout << (int)manzyu(barabara) + prad << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
int rec(vector<char> &cur);

map<vector<char>, int> dp;

int make(vector<char> &cur, int idx, int sum) {
  if (sum > 10)
    return (0);
  if (sum == 10)
    return (rec(cur) + 1);
  if (idx == 10)
    return (0);
  int ret = 0;
  if (cur[idx] > 0) {
    cur[idx]--;
    ret += make(cur, idx, sum + idx);
    cur[idx]++;
  }
  ret = max(ret, make(cur, idx + 1, sum));
  return (ret);
}

int rec(vector<char> &cur) {
  // if(dp.find(cur) != dp.end()) return(dp[cur]);
  return (dp[cur] = make(cur, 1, 0));
}

int main() {
  int n;
  while (cin >> n, n) {

    vector<char> cur(10, 0);
    for (int i = 0; i < n; i++) {
      int digit;
      cin >> digit;
      cur[digit]++;
    }
    int build = 0;
    for (int i = 1; i < 5; i++) {
      int cost = min(cur[i], cur[10 - i]);
      build += cost;
      cur[i] -= cost;
      cur[10 - i] -= cost;
    }
    build += cur[5] / 2;
    cur[5] -= cur[5] / 2;
    cout << build + rec(cur) << endl;
  }
}