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

#include <algorithm>
#include <iostream>
using namespace std;
int dp[100][65536], c[30][16], d[30][16];
int n, m, p[16], q[16];
int _count() {
  int cnt2 = 0;
  for (int i = 0; i < 16; i++) {
    cnt2 += q[i] * (1 << i);
  }
  return cnt2;
}
int main() {
  while (true) {
    for (int i = 0; i < 100; i++) {
      for (int j = 0; j < 65536; j++) {
        dp[i][j] = -1;
        c[i % 30][j % 16] = 0;
        d[i % 30][j % 16] = 0;
      }
    }
    cin >> n >> m;
    int cnt = 0;
    if (n == 0 && m == 0) {
      break;
    }
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < 16; j++) {
        cin >> c[i][j];
      }
    }
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < 16; j++) {
        cin >> d[i][j];
      }
    }
    for (int i = 0; i < n; i++) {
      cnt += c[0][i] * (1 << i);
    }
    dp[0][0] = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < 65536; j++) {
        if (dp[i][j] == -1) {
          continue;
        }
        for (int k = 0; k < 16; k++) {
          p[k] = (j / (1 << k)) % 2;
        }
        for (int k = 0; k < 16; k++) {
          if (c[i][k] == 1) {
            p[k] = 1;
          }
        }
        for (int k = 0; k < m; k++) {
          for (int l = 0; l < 16; l++) {
            q[l] = p[l];
          }
          cnt = 0;
          for (int l = 0; l < 16; l++) {
            if (d[k][l] == 1) {
              if (q[l] == 1) {
                cnt++;
              }
              q[l] = 0;
            }
          }
          dp[i + 1][_count()] = max(dp[i + 1][_count()], dp[i][j] + cnt);
        }
      }
    }
    int minx = 0;
    for (int i = 0; i < 65536; i++) {
      minx = max(minx, dp[n][i]);
    }
    cout << minx << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
using namespace std;
int n, c, d[1000][16], g[1000][16], x[1000][65536], y[16], z[16], sum, sum2;
int main() {
  while (true) {
    for (int i = 0; i < 30; i++) {
      for (int j = 0; j < 65536; j++) {
        x[i][j] = -1;
      }
    }
    cin >> n >> c;
    if (n == 0 && c == 0) {
      break;
    }
    for (int i = 1; i <= n; i++) {
      for (int j = 0; j < 16; j++) {
        cin >> d[i][j];
      }
    }
    for (int i = 0; i < c; i++) {
      for (int j = 0; j < 16; j++) {
        cin >> g[i][j];
      }
    }
    x[0][0] = 0;
    for (int i = 1; i <= n; i++) {
      for (int j = 0; j < 65536; j++) {
        if (x[i - 1][j] >= 0) {
          for (int k = 0; k < 16; k++) {
            y[k] = (j / (1 << k)) % 2;
            if (d[i][k] == 1) {
              y[k] = 1;
            }
          }
          for (int k = 0; k <= c; k++) {
            sum = 0;
            for (int l = 0; l < 16; l++) {
              if (y[l] == 1 && g[k][l] == 1) {
                sum++;
                z[l] = 0;
              } else {
                z[l] = y[l];
              }
            }
            sum2 = 0;
            for (int l = 0; l < 16; l++) {
              sum2 += z[l] * (1 << l);
            }
            x[i][sum2] = max(x[i][sum2], x[i - 1][j] + sum);
          }
        }
      }
    }
    sum = 0;
    for (int i = 0; i < 65536; i++) {
      sum = max(sum, x[n][i]);
    }
    cout << sum << endl;
  }
}