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

#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <vector>

#define N 16
using namespace std;
typedef long long int lli;
const int infty = (1LL << 31) - 1;

bool vis[N];
int Mat[N][N];
int A[N];
int D[N];
int best_ans;

void dfs(int n, int now, int now_ans) {
  if (now_ans >= best_ans)
    return;
  if (now == n) {
    best_ans = min(best_ans, now_ans);
    return;
  }
  for (int i = 0; i < n; ++i) {
    if (!vis[i]) {
      vis[i] = true;
      A[now] = i;
      int distant = now > 0 ? distant = Mat[i][A[now - 1]] : 0;
      int sumd = 0;
      for (int j = now - 2; j >= 0; --j) {
        sumd += D[j];
        distant = max(distant, Mat[i][A[j]] - sumd);
      }
      if (now > 0)
        D[now - 1] = distant;
      dfs(n, now + 1, now_ans + distant);
      vis[i] = false;
    }
  }
  return;
}

int main() {
  while (true) {
    int tMat[N][N] = {
        {
            0,
        },
    };
    int n;
    cin >> n;
    if (n == 0)
      break;
    for (int i = 0; i < n; ++i) {
      vis[i] = false;
      for (int j = 0; j < n; ++j) {
        cin >> tMat[i][j];
      }
    }

    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        Mat[i][j] = max(tMat[j][i], tMat[i][j]);
      }
    }

    best_ans = infty;
    dfs(n, 0, 0);
    if (n <= 1)
      best_ans = 0;
    cout << best_ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <vector>

#define N 16
using namespace std;
typedef long long int lli;
const lli infty = 1LL << 54;

int solve(int p[], int n, int Mat[][N]) {
  int ret = 999999999;
  int *pc, *q, k, t;

  int c[N];
  for (k = 1, q = p, pc = c; k <= n;)
    *q++ = *pc++ = k++;
  k = 1;
  pc = c;
  do {
    t = *(p + k);
    *(p + k) = *(q = p + ((k & 1) ? *pc : 0));
    *q = t;

    // TODO
    int tmp = 0;
    /*for(int i = 0; i < n; ++i){
      printf("%d ", p[i]);
    }
    putchar('\\n');*/
    for (int i = 0; i < n - 1; ++i) {
      int sumt = 0;
      for (int j = i; j < n - 1; ++j) {
        sumt += Mat[p[j] - 1][p[j + 1] - 1];
        if (sumt >= Mat[p[i] - 1][p[j + 1] - 1]) {
          i = j;
          break;
        }
      }
      tmp += sumt;
      if (tmp > ret)
        break;
    }
    ret = min(ret, tmp);

    k = 1;
    pc = c;
    while (*pc == 0)
      *pc++ = k++;
    (*pc)--;
  } while (k < n);
  return ret;
}

bool vis[N];
int Mat[N][N];
int A[N];
lli best_ans;

void dfs(int n, int now, lli now_ans) {
  if (now_ans >= best_ans)
    return;
  if (now == n) {
    best_ans = min(best_ans, now_ans);
    return;
  }
  for (int i = 0; i < n; ++i) {
    if (!vis[i]) {
      vis[i] = true;
      A[now] = i;
      lli distant = now > 0 ? distant = Mat[i][A[now - 1]] : 0;
      lli sumt = 0;
      for (int j = now - 2; j >= 0; --j) {
        sumt += Mat[A[j]][A[j + 1]];
        distant = max(distant, Mat[i][A[j]] - sumt);
      }
      dfs(n, now + 1, now_ans + distant);
      vis[i] = false;
    }
  }
  return;
}

int main() {

  while (true) {
    int tMat[N][N] = {
        {
            0,
        },
    };
    int n;
    cin >> n;
    if (cin.eof())
      break;
    for (int i = 0; i < n; ++i) {
      vis[i] = false;
      for (int j = 0; j < n; ++j) {
        cin >> tMat[i][j];
      }
    }
    /*
    for(int i = 0; i < n; ++i){
      for(int j = 0; j < n; ++j){
        cout << setw(6) << tMat[i][j] << ' ';
      }
      cout << endl;
    }
    cout << endl;
    */
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        Mat[i][j] = max(tMat[j][i], tMat[i][j]);
      }
    }

    best_ans = infty;

    dfs(n, 0, 0);
    if (n <= 1)
      best_ans = 0;
    cout << best_ans << endl;
  }
  return 0;
}