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

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
int R, C;
string ss[201];
int dp[2][1 << 16];
const int INF = 1 << 30;
int bitPos[1 << 16][18];
int bitCnt[1 << 16][18];
int main() {
  for (int mask = 0; mask < (1 << 16); mask++) {
    int a = 0;
    for (int i = 0; i < 16; i++) {
      if (((mask >> i) & 1))
        bitPos[mask][i] = a++;
      else
        bitPos[mask][i] = -1;
      bitCnt[mask][i + 1] = bitCnt[mask][i] + ((mask >> i) & 1);
    }
  }
  cin >> R >> C;
  for (int i = 0; i < R; i++)
    cin >> ss[i];
  for (int i = R * C; i >= 0; i--) {
    int cur = i % 2;
    int nxt = cur ^ 1;
    const int cy = i / C;
    const int cx = i % C;
    for (int mask = 0; mask < (1 << C); mask++) {
      int res = -INF;
      if (i == R * C)
        res = 0;
      else {
        int cnt = 0;
        if (cy - 1 >= 0)
          cnt = (int)ss[cy - 1].size() - (bitCnt[mask][16] - bitCnt[mask][cx]);
        const int ct = bitCnt[mask][cx];
        if (ct < (int)ss[cy].size()) {
          int nmask = mask | (1 << cx);
          int add = 0;
          if (cx - 1 >= 0 && bitPos[mask][cx - 1] != -1 &&
              bitPos[mask][cx - 1] < (int)ss[cy].size() &&
              bitPos[mask][cx - 1] + 1 < (int)ss[cy].size() &&
              ss[cy][bitPos[mask][cx - 1]] ==
                  ss[cy][bitPos[mask][cx - 1] + 1]) {
            add += 2;
          }
          if (cy - 1 >= 0 && bitPos[mask][cx] != -1 &&
              cnt < (int)ss[cy - 1].size() &&
              bitCnt[mask][cx] < (int)ss[cy].size() &&
              ss[cy - 1][cnt] == ss[cy][bitCnt[mask][cx]]) {
            add += 2;
          }
          if (cx != C - 1 || ct + 1 == (int)ss[cy].size()) {
            res = max(res, dp[nxt][nmask] + add);
          }
        }
        {
          int nmask = mask & ~(1 << cx);
          if (cx != C - 1 || ct == (int)ss[cy].size()) {
            res = max(res, dp[nxt][nmask]);
          }
        }
      }
      dp[cur][mask] = res;
    }
  }
  cout << dp[0][0] << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
int R, C;
string ss[201];
int dp[2][1 << 16][20];
const int INF = 1 << 30;
int bitPos[1 << 16][17];
int bitCnt[1 << 16][17];
int main() {
  for (int mask = 0; mask < (1 << 16); mask++) {
    int a = 0;
    for (int i = 0; i < 16; i++) {
      if (((mask >> i) & 1))
        bitPos[mask][i] = a++;
      else
        bitPos[mask][i] = -1;
      bitCnt[mask][i + 1] = bitCnt[mask][i] + ((mask >> i) & 1);
    }
  }
  cin >> R >> C;
  for (int i = 0; i < R; i++)
    cin >> ss[i];
  for (int i = R * C; i >= 0; i--) {
    int cur = i % 2;
    int nxt = cur ^ 1;
    const int cy = i / C;
    const int cx = i % C;
    for (int mask = 0; mask < (1 << C); mask++) {
      for (int k = 0; k < 16; k++) {
        int res = -INF;
        if (i == R * C)
          res = 0;
        else {
          const int cnt = k;
          const int ct = bitCnt[mask][cx];
          if (ct < (int)ss[cy].size()) {
            int nmask = mask | (1 << cx);
            int add = 0;
            if (cx - 1 >= 0 && bitPos[mask][cx - 1] != -1 &&
                bitPos[mask][cx - 1] < (int)ss[cy].size() &&
                bitPos[mask][cx - 1] + 1 < (int)ss[cy].size() &&
                ss[cy][bitPos[mask][cx - 1]] ==
                    ss[cy][bitPos[mask][cx - 1] + 1]) {
              add += 2;
            }
            if (cy - 1 >= 0 && bitPos[mask][cx] != -1 &&
                cnt < (int)ss[cy - 1].size() &&
                bitCnt[mask][cx] < (int)ss[cy].size() &&
                ss[cy - 1][cnt] == ss[cy][bitCnt[mask][cx]]) {
              add += 2;
            }
            if (cx != C - 1 || ct + 1 == (int)ss[cy].size()) {
              if (cx == C - 1)
                res = max(res, dp[nxt][nmask][0] + add);
              else
                res = max(res, dp[nxt][nmask][k + ((mask >> cx) & 1)] + add);
            }
          }
          {
            int nmask = mask & ~(1 << cx);
            if (cx != C - 1 || ct == (int)ss[cy].size()) {
              if (cx == C - 1)
                res = max(res, dp[nxt][nmask][0]);
              else
                res = max(res, dp[nxt][nmask][k + ((mask >> cx) & 1)]);
            }
          }
        }
        dp[cur][mask][k] = res;
      }
    }
  }
  cout << dp[0][0][0] << endl;
  return 0;
}