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

#include <iostream>
using namespace std;

int search(int s);
int num[50], a[50], u[50], d[51], n, g;

int fnd(int v, int t, int s, int k) {
  int i, j, w = -1;
  if (k == 0) {
    j = a[v];
    a[v] = 0;
    if (g == n || search(t + 1) == 1)
      return 1;
    a[v] = j;
    return 0;
  }
  if (k > d[s] || t == n - 1)
    return 0;
  for (i = s; i < n; i++) {
    if (u[i] == 0 && a[i] != w && k - a[i] >= 0) {
      u[i] = 1;
      g++;
      if (fnd(v, t, i + 1, k - a[i]) == 1)
        return 1;
      u[i] = 0;
      g--;
      w = a[i];
    }
  }
  return 0;
}

int search(int s) {
  int i, k;
  if (g == n)
    return 1;
  while (u[s] == 1 && s < n)
    s++;
  if (s == n)
    return 0;
  for (i = 0; i < s; i++)
    if (a[i] >= a[s]) {
      a[i] -= a[s];
      g++;
      if (a[i] == 0) {
        u[s] = 1;
        k = search(s + 1);
      } else
        k = fnd(i, s, s + 1, a[i]);
      if (k == 1)
        return 1;
      else {
        a[i] += a[s];
        u[s] = 0;
        g--;
      }
    }
  return 0;
}

int main() {
  int i, j, k;

  while (cin >> n) {
    if (n == 0)
      break;
    for (i = 0; i < n; i++) {
      cin >> num[i];
    }
    for (i = n - 1; i > 0; i--)
      for (j = 0; j < i; j++)
        if (num[j] < num[j + 1]) {
          k = num[j];
          num[j] = num[j + 1];
          num[j + 1] = k;
        }
    d[n] = 0;
    for (i = n - 1; i >= 0; i--) {
      a[i] = num[i];
      d[i] = d[i + 1] + num[i];
      u[i] = 0;
    }
    u[0] = 1;
    g = 1;
    if (search(1) == 1)
      cout << "YES" << endl;
    else
      cout << "NO" << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
using namespace std;

int search(int s);
int num[50], a[50], u[50], d[51], n, g;

int fnd(int v, int t, int s, int k) {
  int i, j, w = -1;
  if (k == 0) {
    j = a[v];
    a[v] = 0;
    if (g == n || search(s + 1) == 1)
      return 1;
    a[v] = j;
    return 0;
  }
  if (k > d[s] || t == n - 1)
    return 0;
  for (i = s; i < n; i++) {
    if (u[i] == 0 && a[i] != w && k - a[i] >= 0) {
      u[i] = 1;
      g++;
      if (fnd(v, t, i + 1, k - a[i]) == 1)
        return 1;
      u[i] = 0;
      g--;
      w = a[i];
    }
  }
  return 0;
}

int search(int s) {
  int i, k;
  if (g == n)
    return 1;
  while (u[s] == 1 && s < n)
    s++;
  if (s == n)
    return 0;
  for (i = 0; i < s; i++)
    if (a[i] >= a[s]) {
      a[i] -= a[s];
      g++;
      if (a[i] == 0) {
        u[s] = 1;
        k = search(s + 1);
      } else
        k = fnd(i, s, s + 1, a[i]);
      if (k == 1)
        return 1;
      else {
        a[i] += a[s];
        u[s] = 0;
        g--;
      }
    }
  return 0;
}

int main() {
  int i, j, k;
  while (cin >> n) {
    if (n == 0)
      break;
    for (i = 0; i < n; i++) {
      cin >> num[i];
    }
    for (i = n - 1; i > 0; i--)
      for (j = 0; j < i; j++)
        if (num[j] < num[j + 1]) {
          k = num[j];
          num[j] = num[j + 1];
          num[j + 1] = k;
        }
    d[n] = 0;
    for (i = n - 1; i >= 0; i--) {
      a[i] = num[i];
      d[i] = d[i + 1] + num[i];
      u[i] = 0;
    }
    u[0] = 1;
    g = 1;
    if (search(1) == 1)
      cout << "YES" << endl;
    else
      cout << "NO" << endl;
  }
  return 0;
}