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

// 1 から 1000 まで答えを計算するのに 5 min 30 sec
/*
#include<algorithm>
#include<cstdio>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

int tar;

int hstar(int n,const int *a){
        int a_max=*max_element(a,a+n);
        int res=0;
        while(a_max<tar) a_max*=2, res++;
        return res;
}

bool dfs(int n,int *a,int ub){
        rep(i,n) if(a[i]==tar) return true;

        if((n-1)>=ub || (n-1)+hstar(n,a)>ub) return false;

        rep(i,n) rep(j,n) {
                bool ok1=true,ok2=true;
                rep(k,n){
                        if(a[i]+a[j]==a[k]) ok1=false;
                        if(a[i]-a[j]==a[k]) ok2=false;
                }
                if(ok1 && i<=j){
                        a[n]=a[i]+a[j];
                        if(dfs(n+1,a,ub)) return true;
                }
                if(ok2 && a[i]-a[j]>0){
                        a[n]=a[i]-a[j];
                        if(dfs(n+1,a,ub)) return true;
                }
        }
        return false;
}

int main(){
        for(tar=1;tar<=1000;tar++){
                int a[20]={1},ub;
                for(ub=0;ub<=12&&!dfs(1,a,ub);ub++);
                printf("%d,",ub);
        }
        return 0;
}
*/

#include <cstdio>

using namespace std;

const int emb[1001] = {
    -1, 0,  1,  2,  2,  3,  3,  4,  3,  4,  4,  5,  4,  5,  5,  5,  4,  5,  5,
    6,  5,  6,  6,  6,  5,  6,  6,  6,  6,  7,  6,  6,  5,  6,  6,  7,  6,  7,
    7,  7,  6,  7,  7,  7,  7,  7,  7,  7,  6,  7,  7,  7,  7,  8,  7,  8,  7,
    8,  8,  8,  7,  8,  7,  7,  6,  7,  7,  8,  7,  8,  8,  8,  7,  8,  8,  8,
    8,  8,  8,  8,  7,  8,  8,  8,  8,  8,  8,  9,  8,  9,  8,  9,  8,  8,  8,
    8,  7,  8,  8,  8,  8,  9,  8,  9,  8,  9,  9,  9,  8,  9,  9,  9,  8,  9,
    9,  9,  9,  9,  9,  9,  8,  9,  9,  9,  8,  9,  8,  8,  7,  8,  8,  9,  8,
    9,  9,  9,  8,  9,  9,  9,  9,  9,  9,  9,  8,  9,  9,  9,  9,  9,  9,  10,
    9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  9,  9,  9,  9,  9,  10, 9,  10, 9,
    10, 9,  10, 10, 10, 9,  10, 10, 10, 9,  10, 10, 10, 9,  10, 9,  10, 9,  9,
    9,  9,  8,  9,  9,  9,  9,  10, 9,  10, 9,  10, 10, 10, 9,  10, 10, 10, 9,
    10, 10, 10, 10, 10, 10, 10, 9,  10, 10, 10, 10, 10, 10, 10, 9,  10, 10, 10,
    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9,  10, 10, 10, 10, 10, 10,
    10, 9,  10, 10, 10, 9,  10, 9,  9,  8,  9,  9,  10, 9,  10, 10, 10, 9,  10,
    10, 11, 10, 11, 10, 10, 9,  10, 10, 11, 10, 11, 10, 10, 10, 10, 10, 10, 10,
    10, 10, 10, 9,  10, 10, 10, 10, 10, 10, 11, 10, 10, 10, 11, 10, 11, 11, 11,
    10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 10, 10, 10, 10, 10, 9,  10, 10,
    10, 10, 10, 10, 11, 10, 11, 10, 11, 10, 11, 11, 11, 10, 11, 11, 11, 10, 11,
    11, 11, 10, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 11, 11, 11, 11, 11, 10,
    11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 11, 10, 11, 11, 11, 10, 11, 10, 11,
    10, 10, 10, 10, 9,  10, 10, 10, 10, 11, 10, 11, 10, 11, 11, 11, 10, 11, 11,
    11, 10, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 11, 11, 11, 11, 11, 10, 11,
    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 11, 11,
    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 11, 11, 11, 11, 11,
    11, 11, 11, 11, 11, 12, 11, 12, 11, 11, 11, 12, 11, 12, 11, 11, 11, 11, 11,
    11, 11, 11, 11, 11, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 11, 12,
    11, 11, 10, 11, 11, 12, 11, 12, 11, 11, 10, 11, 11, 11, 10, 11, 10, 10, 9,
    10, 10, 11, 10, 11, 11, 11, 10, 11, 11, 12, 11, 12, 11, 11, 10, 11, 11, 12,
    11, 12, 12, 11, 11, 12, 12, 12, 11, 12, 11, 11, 10, 11, 11, 12, 11, 12, 12,
    12, 11, 11, 12, 12, 11, 12, 11, 12, 11, 11, 11, 12, 11, 12, 11, 11, 11, 12,
    11, 11, 11, 11, 11, 11, 10, 11, 11, 11, 11, 11, 11, 12, 11, 11, 11, 12, 11,
    12, 12, 12, 11, 12, 11, 12, 11, 12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 12,
    11, 12, 12, 12, 11, 12, 12, 12, 11, 12, 12, 12, 11, 12, 12, 12, 11, 12, 12,
    12, 11, 12, 11, 12, 11, 12, 11, 11, 11, 11, 11, 11, 10, 11, 11, 11, 11, 11,
    11, 12, 11, 12, 11, 12, 11, 12, 12, 12, 11, 12, 12, 12, 11, 12, 12, 12, 11,
    12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 12,
    12, 12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
    12, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12,
    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 12, 12,
    12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 12, 11, 12, 12, 12,
    11, 12, 11, 12, 11, 11, 11, 11, 10, 11, 11, 11, 11, 12, 11, 12, 11, 12, 12,
    12, 11, 12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 12, 12, 12,
    12, 12, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 12, 12, 12, 12, 11,
    12, 12, 12, 12, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 12,
    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 12, 12, 12, 13, 12, 13, 12,
    12, 12, 13, 12, 12, 12, 12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 13, 12, 12,
    12, 13, 12, 13, 12, 12, 12, 13, 12, 13, 12, 13, 12, 12, 12, 12, 12, 12, 12,
    12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 12, 13, 12, 13,
    12, 13, 12, 13, 12, 13, 12, 13, 12, 13, 13, 13, 12, 13, 13, 13, 12, 13, 12,
    13, 12, 13, 13, 13, 12, 13, 13, 13, 12, 13, 12, 13, 12, 12, 12, 13, 12, 13,
    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 12, 12,
    12, 12, 13, 12, 13, 12, 12, 12, 12, 12, 13, 12, 13, 13, 13, 12, 13, 13, 13,
    12, 13, 12, 12, 11, 12, 12, 13, 12, 13, 13, 13, 12};

int main() {
  for (int n; scanf("%d", &n), n;)
    printf("%d\\n", emb[n]);
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

int tar;

int hstar(int n, const int *a) {
  int a_max = *max_element(a, a + n);
  int res = 0;
  while (a_max < tar)
    a_max *= 2, res++;
  return res;
}

bool dfs(int n, int *a, int ub) {
  rep(i, n) if (a[i] == tar) return true;

  if ((n - 1) >= ub || (n - 1) + hstar(n, a) > ub)
    return false;

  rep(i, n) rep(j, n) {
    bool ok1 = true, ok2 = true;
    rep(k, n) {
      if (a[i] + a[j] == a[k])
        ok1 = false;
      if (a[i] - a[j] == a[k])
        ok2 = false;
    }
    if (ok1 && i <= j) {
      a[n] = a[i] + a[j];
      if (dfs(n + 1, a, ub))
        return true;
    }
    if (ok2 && a[i] - a[j] > 0) {
      a[n] = a[i] - a[j];
      if (dfs(n + 1, a, ub))
        return true;
    }
  }
  return false;
}

int main() {
  for (; scanf("%d", &tar), tar;) {
    int a[20] = {1}, ub;
    for (ub = 0; ub <= 12 && !dfs(1, a, ub); ub++)
      ;
    printf("%d\\n", ub);
  }
  return 0;
}