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

#include <bits/stdc++.h>
using namespace std;
int N, X, Y;
int dp[1001][1001];
int G[14][14];
int DP[(1 << 14)][14];
int mem[(1 << 14)][1001];

int main() {
  scanf("%d %d %d", &N, &X, &Y);
  for (int id = 0; id < N; id++) {
    for (int i = 0; i <= Y; i++)
      dp[id][i] = -1e9;
    dp[id][0] = 0;
    int K;
    scanf("%d", &K);
    for (int i = 0; i < K; i++) {
      int a, b, c;
      scanf("%d %d %d", &a, &b, &c);
      for (int j = 0; j < 10; j++) {
        int na = a * (1 << j);
        int nb = b * (1 << j);
        if (c - (1 << j) < 0) {
          na = a * c;
          nb = b * c;
          c = 0;
        } else {
          c -= (1 << j);
        }
        for (int k = Y; k >= na; k--) {
          if (dp[id][k] < dp[id][k - na] + nb) {
            dp[id][k] = dp[id][k - na] + nb;
          }
        }
        if (c == 0) {
          break;
        }
      }
    }

    for (int i = 1; i <= Y; i++) {
      if (dp[id][i] < dp[id][i - 1]) {
        dp[id][i] = dp[id][i - 1];
      }
    }
  }

  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      scanf("%d", &G[i][j]);
    }
  }
  for (int k = 0; k < N; k++) {
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        if (G[i][k] + G[k][j] < G[i][j]) {
          G[i][j] = G[i][k] + G[k][j];
        }
      }
    }
  }

  for (int i = 0; i < (1 << N); i++) {
    for (int j = 0; j < N; j++) {
      DP[i][j] = 100000000;
    }
  }

  DP[0][0] = 0;
  for (int bit = 0; bit < (1 << N); bit++) {
    for (int pos = 0; pos < N; pos++) {
      for (int to = 0; to < N; to++) {
        int nbit = bit | (1 << to);
        int ncost = DP[bit][pos] + G[pos][to];
        if (DP[nbit][to] > ncost) {
          DP[nbit][to] = ncost;
        }
      }
    }
  }

  mem[0][0] = 0;
  for (int i = 0; i <= Y; i++)
    mem[0][i] = -1e9;

  int ans = 0;
  int tmp[1001];

  for (int bit = 1; bit < (1 << N); bit++) {
    int ny = min(Y, X - DP[bit][0]);

    int dit = bit - (bit & -bit);
    for (int i = 0; i <= Y; i++)
      tmp[i] = mem[dit][i];
    tmp[0] = 0;

    for (int i = 0; i < N; i++) {
      if ((bit >> i & 1)) {
        for (int j = Y; j >= 0; j--) {
          int cc;
          cc = 0;
          for (int k = 0; k <= j; k++) {
            cc++;
            if (cc >= 100000 / Y)
              break;
            if (tmp[j] < tmp[j - k] + dp[i][k]) {
              tmp[j] = tmp[j - k] + dp[i][k];
            }
          }
          cc = 0;
          for (int k = j; k >= 0; k--) {
            cc++;
            if (cc >= 20000 / Y)
              break;
            if (tmp[j] < tmp[j - k] + dp[i][k]) {
              tmp[j] = tmp[j - k] + dp[i][k];
            }
          }
        }
        break;
      }
    }
    if (ny >= 0 && ans < tmp[ny]) {
      ans = tmp[ny];
    }
    for (int i = 0; i <= Y; i++)
      mem[bit][i] = tmp[i];
  }

  printf("%d\\n", ans);
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
int N, X, Y;
int dp[1001][1001];
int G[14][14];
int DP[(1 << 14)][14];
int mem[(1 << 14)][1001];

int main() {
  scanf("%d %d %d", &N, &X, &Y);
  for (int id = 0; id < N; id++) {
    for (int i = 0; i <= Y; i++)
      dp[id][i] = -1e9;
    dp[id][0] = 0;
    int K;
    scanf("%d", &K);
    for (int i = 0; i < K; i++) {
      int a, b, c;
      scanf("%d %d %d", &a, &b, &c);
      for (int j = 0; j < 10; j++) {
        int na = a * (1 << j);
        int nb = b * (1 << j);
        if (c - (1 << j) < 0) {
          na = a * c;
          nb = b * c;
          c = 0;
        } else {
          c -= (1 << j);
        }
        for (int k = Y; k >= na; k--) {
          if (dp[id][k] < dp[id][k - na] + nb) {
            dp[id][k] = dp[id][k - na] + nb;
          }
        }
        if (c == 0) {
          break;
        }
      }
    }

    for (int i = 1; i <= Y; i++) {
      if (dp[id][i] < dp[id][i - 1]) {
        dp[id][i] = dp[id][i - 1];
      }
    }
  }

  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      scanf("%d", &G[i][j]);
    }
  }
  for (int k = 0; k < N; k++) {
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        if (G[i][k] + G[k][j] < G[i][j]) {
          G[i][j] = G[i][k] + G[k][j];
        }
      }
    }
  }

  for (int i = 0; i < (1 << N); i++) {
    for (int j = 0; j < N; j++) {
      DP[i][j] = 100000000;
    }
  }

  DP[0][0] = 0;
  for (int bit = 0; bit < (1 << N); bit++) {
    for (int pos = 0; pos < N; pos++) {
      for (int to = 0; to < N; to++) {
        int nbit = bit | (1 << to);
        int ncost = DP[bit][pos] + G[pos][to];
        if (DP[nbit][to] > ncost) {
          DP[nbit][to] = ncost;
        }
      }
    }
  }

  mem[0][0] = 0;
  for (int i = 0; i <= Y; i++)
    mem[0][i] = -1e9;

  int ans = 0;
  int tmp[1001];

  for (int bit = 1; bit < (1 << N); bit++) {
    int ny = min(Y, X - DP[bit][0]);

    int dit = bit - (bit & -bit);
    for (int i = 0; i <= Y; i++)
      tmp[i] = mem[dit][i];
    tmp[0] = 0;

    for (int i = 0; i < N; i++) {
      if ((bit >> i & 1)) {
        for (int j = Y; j >= 0; j--) {
          int cc;
          cc = 0;
          for (int k = 0; k <= j; k++) {
            cc++;
            if (cc >= 90000 / Y)
              break;
            if (tmp[j] < tmp[j - k] + dp[i][k]) {
              tmp[j] = tmp[j - k] + dp[i][k];
            }
          }
          cc = 0;
          for (int k = j; k >= 0; k--) {
            cc++;
            if (cc >= 90000 / Y)
              break;
            if (tmp[j] < tmp[j - k] + dp[i][k]) {
              tmp[j] = tmp[j - k] + dp[i][k];
            }
          }
        }
        break;
      }
    }
    if (ny >= 0 && ans < tmp[ny]) {
      ans = tmp[ny];
    }
    for (int i = 0; i <= Y; i++)
      mem[bit][i] = tmp[i];
  }

  printf("%d\\n", ans);
  return 0;
}