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

#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
typedef pair<int, int> pr;
typedef pair<pr, pr> ppr;
typedef pair<int, vector<int>> pv;
int num[5] = {}, numTimes[5] = {}, numbers, alls;
vector<pv> p;
void search(int times, int gets[5]) {
  if (times == numbers) {

    int sum = 0;
    for (int i = 0; i < numbers; i++)
      sum += num[i] * gets[i];
    if (sum == 10) {
      pv a;
      a.first = -1;
      for (int i = 0; i < numbers; i++) {
        a.second.push_back(gets[i]);
        if (a.first == -1 && gets[i] != 0)
          a.first = 100 - num[i];
      }

      p.push_back(a);
    }
  } else {
    for (int i = 0; i <= numTimes[times] && i <= 10; i++) {
      gets[times] = i;
      search(times + 1, gets);
    }
  }
}
int findAns(int x, int times[]) {
  if (x == p.size())
    return 0;
  int maxim = 0, ans = 1;
  int ar[5];
  for (int i = 0; i < 5; i++)
    ar[i] = p[x].second[i];
  for (int i = 0; i < numbers; i++) {
    if (ar[i] > times[i])
      ans = 0;
    times[i] -= ar[i];
  }
  if (ans)
    maxim = max(maxim, 1 + findAns(x, times));
  for (int i = 0; i < numbers; i++)
    times[i] += ar[i];
  maxim = max(maxim, findAns(x + 1, times));
  return maxim;
}
int solved(vector<pr> v) {
  int ans = 0;
  for (int i = 0; i < v.size(); i++) {
    num[i] = v[i].first;
    numTimes[i] = v[i].second;
  }
  sort(v.begin(), v.end());
  numbers = v.size();
  int gets[5] = {};
  alls = 0;
  for (int i = 0; i < numbers; i++)
    alls += num[i] * numTimes[i];
  sort(p.begin(), p.end());
  search(0, gets);
  return findAns(0, numTimes);
}
int main() {
  // your code goes here
  int n, tmp;
  while (cin >> n && n != 0) {
    p.clear();
    for (int i = 0; i < 5; i++) {
      num[i] = 0;
      numTimes[i] = 0;
    }

    numbers = 0;
    vector<pr> v;
    int nums[10] = {}, sum = 0;
    for (int i = 0; i < n; i++) {
      cin >> tmp;
      nums[tmp]++;
    }
    for (int i = 1; i <= 4; i++)
      if (nums[i] && nums[10 - i]) {
        int manju = min(nums[i], nums[10 - i]);
        sum += manju;
        nums[i] -= manju;
        nums[10 - i] -= manju;
      }
    sum += nums[5] / 2;
    nums[5] %= 2;
    while (nums[3] >= 2 && nums[4] >= 1) {
      nums[3] -= 2;
      nums[4] -= 1;
      sum++;
    }
    for (int i = 1; i <= 8; i++)
      if (nums[i])
        v.push_back(pr(i, nums[i]));
    cout << sum + solved(v) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
typedef pair<int, int> pr;
typedef pair<pr, pr> ppr;
int num[5] = {}, numTimes[5] = {}, numbers;
vector<vector<int>> p;
void search(int times, int gets[5]) {
  if (times == numbers) {

    int sum = 0;
    for (int i = 0; i < numbers; i++)
      sum += num[i] * gets[i];
    if (sum == 10) {
      vector<int> a = {gets[0], gets[1], gets[2], gets[3], gets[4]};
      p.push_back(a);
    }
  } else {
    for (int i = 0; i <= numTimes[times] && i <= 10; i++) {
      gets[times] = i;
      search(times + 1, gets);
    }
  }
}
int findAns(int x, int times[]) {
  if (x == p.size())
    return 0;
  int maxim = 0, ans = 1;
  int ar[5];
  for (int i = 0; i < 5; i++)
    ar[i] = p[x][i];
  for (int i = 0; i < numbers; i++) {
    if (ar[i] > times[i])
      ans = 0;
    times[i] -= ar[i];
  }
  if (ans)
    maxim = max(maxim, 1 + findAns(x, times));
  for (int i = 0; i < numbers; i++)
    times[i] += ar[i];
  maxim = max(maxim, findAns(x + 1, times));
  return maxim;
}
int solved(vector<pr> v) {
  int ans = 0;
  for (int i = 0; i < v.size(); i++) {
    num[i] = v[i].first;
    numTimes[i] = v[i].second;
  }
  numbers = v.size();
  int gets[5] = {};
  search(0, gets);
  return findAns(0, numTimes);
}
int main() {
  // your code goes here
  int n, tmp;
  while (cin >> n && n != 0) {
    p.clear();
    numbers = 0;
    vector<pr> v;
    int nums[10] = {}, sum = 0;
    for (int i = 0; i < n; i++) {
      cin >> tmp;
      nums[tmp]++;
    }
    for (int i = 1; i <= 4; i++)
      if (nums[i] && nums[10 - i]) {
        int manju = min(nums[i], nums[10 - i]);
        sum += manju;
        nums[i] -= manju;
        nums[10 - i] -= manju;
      }
    sum += nums[5] / 2;
    nums[5] %= 2;
    for (int i = 1; i <= 8; i++)
      if (nums[i])
        v.push_back(pr(i, nums[i]));
    cout << sum + solved(v) << endl;
  }
  return 0;
}