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

#include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

struct data {
  int bit;
  int cost;
  int v;
  data() {}
  data(int vv, int bb, int cc) {
    v = vv;
    cost = cc;
    bit = bb;
  }
  bool operator<(const data &dat) const { return cost > dat.cost; }
};

int n, x, y;
int dp[1 << 14][14];
int dp2[14][1001];
int dp3[1 << 14][1001];
int dp4[1 << 14][1001];
int tmp[1001][1001];
int tmp2[1001];
int tmp3[15][1001];
int dist[14][14];
int a[14][301], b[14][301], c[14][301];

void dijk() {
  priority_queue<data> que;
  for (int i = 0; i < (1 << n); i++) {
    for (int j = 0; j < n; j++) {
      dp[i][j] = 100000;
    }
  }
  dp[1][0] = 0;
  que.push(data(0, 1, 0));
  while (que.size()) {
    data d = que.top();
    que.pop();
    if (dp[d.bit][d.v] < d.cost)
      continue;
    for (int nec = 0; nec < n; nec++) {
      int nbit = d.bit | (1 << nec);
      int ncost = d.cost + dist[d.v][nec];
      if (ncost < dp[nbit][nec]) {
        dp[nbit][nec] = ncost;
        que.push(data(nec, nbit, ncost));
      }
    }
  }
}

int main(void) {
  scanf("%d%d%d", &n, &x, &y);
  for (int i = 0; i < n; i++) {
    int k;
    scanf("%d", &k);
    for (int j = 0; j < k; j++) {
      scanf("%d%d%d", &a[i][j], &b[i][j], &c[i][j]);
    }
    memset(tmp, 0, sizeof(tmp));
    for (int j = 0; j < k; j++) {
      memset(tmp3, 0, sizeof(tmp3));
      for (int cs = 0; cs <= y; cs++) {
        tmp3[0][cs] = tmp[j][cs];
      }
      int cnt2 = 0;
      for (int ncs = 0; ncs <= 10; ncs++) {
        int cs = min(c[i][j], (int)(1 << ncs));
        c[i][j] -= cs;
        cnt2++;
        for (int l = 0; l <= y; l++) {
          tmp3[cnt2][l] = max(tmp3[cnt2][l], tmp3[cnt2 - 1][l]);
          if (l + cs * a[i][j] > y)
            continue;
          tmp3[cnt2][l + cs * a[i][j]] = max(tmp3[cnt2][l + cs * a[i][j]],
                                             tmp3[cnt2 - 1][l] + b[i][j] * cs);
        }
      }
      for (int l = 0; l <= y; l++) {
        tmp[j + 1][l] = tmp3[cnt2][l];
      }
    }
    for (int j = 0; j <= y; j++) {
      dp2[i][j] = tmp[k][j];
    }
    for (int j = 1; j <= y; j++) {
      dp2[i][j] = max(dp2[i][j], dp2[i][j - 1]);
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      scanf("%d", &dist[i][j]);
    }
  }
  dijk();
  for (int i = 0; i < n / 2; i++) {
    for (int j = 0; j < (1 << i); j++) {
      for (int k = 0; k <= y; k++) {
        for (int l = k; l <= y; l++) {
          dp3[j | (1 << i)][l] =
              max(dp3[j | (1 << i)][l], dp3[j][k] + dp2[i][l - k]);
        }
      }
    }
  }
  for (int i = 0; i < (n + 1) / 2; i++) {
    for (int j = 0; j < (1 << i); j++) {
      for (int k = 0; k <= y; k++) {
        for (int l = k; l <= y; l++) {
          dp4[j | (1 << i)][l] =
              max(dp4[j | (1 << i)][l], dp4[j][k] + dp2[n / 2 + i][l - k]);
        }
      }
    }
  }
  for (int i = 0; i < (1 << (n / 2)); i++) {
    for (int j = 1; j <= y; j++) {
      dp3[i][j] = max(dp3[i][j], dp3[i][j - 1]);
    }
  }
  for (int i = 0; i < (1 << ((n + 1) / 2)); i++) {
    for (int j = 1; j <= y; j++) {
      dp4[i][j] = max(dp4[i][j], dp4[i][j - 1]);
    }
  }
  int res = 0;
  for (int i = 0; i < (1 << n); i++) {
    int yosan = 0;
    int bit1 = 0;
    int bit2 = 0;
    for (int bit = n - 1; bit >= 0; bit--) {
      bit1 *= 2;
      if (bit >= n / 2)
        bit2 *= 2;
      if (i >> bit & 1) {
        if (bit < n / 2) {
          bit1++;
        } else {
          bit2++;
        }
      }
    }
    for (int j = 0; j < n; j++) {
      yosan = max(yosan, x - dp[i][j] - dist[j][0]);
    }
    yosan = min(y, yosan);
    for (int j = 0; j <= yosan; j++) {
      res = max(res, dp3[bit1][j] + dp4[bit2][yosan - j]);
    }
  }
  printf("%d\\n", res);
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

struct data {
  int bit;
  int cost;
  int v;
  data() {}
  data(int vv, int bb, int cc) {
    v = vv;
    cost = cc;
    bit = bb;
  }
  bool operator<(const data &dat) const { return cost > dat.cost; }
};

int n, x, y;
int dp[1 << 14][14];
int dp2[14][1001];
int dp3[1 << 14][1001];
int dp4[1 << 14][1001];
int tmp[1001][1001];
int tmp2[1001];
int tmp3[15][1001];
int dist[14][14];
int a[14][301], b[14][301], c[14][301];

void dijk() {
  priority_queue<data> que;
  for (int i = 0; i < (1 << n); i++) {
    for (int j = 0; j < n; j++) {
      dp[i][j] = 100000;
    }
  }
  dp[1][0] = 0;
  que.push(data(0, 1, 0));
  while (que.size()) {
    data d = que.top();
    que.pop();
    if (dp[d.bit][d.v] < d.cost)
      continue;
    for (int nec = 0; nec < n; nec++) {
      int nbit = d.bit | (1 << nec);
      int ncost = d.cost + dist[d.v][nec];
      if (ncost < dp[nbit][nec]) {
        dp[nbit][nec] = ncost;
        que.push(data(nec, nbit, ncost));
      }
    }
  }
}

int main(void) {
  scanf("%d%d%d", &n, &x, &y);
  for (int i = 0; i < n; i++) {
    int k;
    scanf("%d", &k);
    for (int j = 0; j < k; j++) {
      scanf("%d%d%d", &a[i][j], &b[i][j], &c[i][j]);
    }
    memset(tmp, 0, sizeof(tmp));
    for (int j = 0; j < k; j++) {
      for (int l = 0; l <= y; l++) {
        for (int cs = 0; cs <= c[i][j]; cs++) {
          if (l + cs * a[i][j] > y)
            break;
          tmp[j + 1][l + cs * a[i][j]] =
              max(tmp[j + 1][l + cs * a[i][j]], tmp[j][l] + b[i][j] * cs);
        }
      }
    }
    for (int j = 0; j <= y; j++) {
      dp2[i][j] = tmp[k][j];
    }
    for (int j = 1; j <= y; j++) {
      dp2[i][j] = max(dp2[i][j], dp2[i][j - 1]);
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      scanf("%d", &dist[i][j]);
    }
  }
  dijk();
  for (int i = 0; i < n / 2; i++) {
    for (int j = 0; j < (1 << i); j++) {
      for (int k = 0; k <= y; k++) {
        for (int l = k; l <= y; l++) {
          dp3[j | (1 << i)][l] =
              max(dp3[j | (1 << i)][l], dp3[j][k] + dp2[i][l - k]);
        }
      }
    }
  }
  for (int i = 0; i < (n + 1) / 2; i++) {
    for (int j = 0; j < (1 << i); j++) {
      for (int k = 0; k <= y; k++) {
        for (int l = k; l <= y; l++) {
          dp4[j | (1 << i)][l] =
              max(dp4[j | (1 << i)][l], dp4[j][k] + dp2[n / 2 + i][l - k]);
        }
      }
    }
  }
  for (int i = 0; i < (1 << (n / 2)); i++) {
    for (int j = 1; j <= y; j++) {
      dp3[i][j] = max(dp3[i][j], dp3[i][j - 1]);
    }
  }
  for (int i = 0; i < (1 << ((n + 1) / 2)); i++) {
    for (int j = 1; j <= y; j++) {
      dp4[i][j] = max(dp4[i][j], dp4[i][j - 1]);
    }
  }
  int res = 0;
  for (int i = 0; i < (1 << n); i++) {
    int yosan = 0;
    int bit1 = 0;
    int bit2 = 0;
    for (int bit = n - 1; bit >= 0; bit--) {
      bit1 *= 2;
      if (bit >= n / 2)
        bit2 *= 2;
      if (i >> bit & 1) {
        if (bit < n / 2) {
          bit1++;
        } else {
          bit2++;
        }
      }
    }
    for (int j = 0; j < n; j++) {
      yosan = max(yosan, x - dp[i][j] - dist[j][0]);
    }
    yosan = min(y, yosan);
    for (int j = 0; j <= yosan; j++) {
      res = max(res, dp3[bit1][j] + dp4[bit2][yosan - j]);
    }
  }
  printf("%d\\n", res);
  return 0;
}