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

#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

unsigned int table[256];
int ldp[8][1 << 8][1 << 8];
int udp[8][1 << 8][1 << 8];

int interp(int bits, int w) {
  bits = (bits << 1) | (bits & 1);
  return bits | ((bits & (1 << w)) << 1);
}

int main() {
  for (int i = 0; i < 256; ++i) {
    unsigned int x = 0;
    for (int j = 0; j < 8; ++j) {
      if (i & (1 << j)) {
        x |= (1 << (j * 4));
      }
    }
    table[i] = x;
  }
  int caseNum = 1;
  while (true) {
    int H, W;
    cin >> W >> H;
    if (H == 0 && W == 0) {
      break;
    }
    vector<string> simage(H);
    for (int i = 0; i < H; ++i) {
      cin >> simage[i];
    }
    vector<int> image(max(H, W));
    if (H >= W) {
      for (int i = 0; i < H; ++i) {
        for (int j = 0; j < W; ++j) {
          image[i] |= (simage[i][j] == '#') << j;
        }
      }
    } else {
      swap(H, W);
      for (int i = 0; i < W; ++i) {
        for (int j = 0; j < H; ++j) {
          image[j] |= (simage[i][j] == '#') << i;
        }
      }
    }
    for (int i = 0; i < H; ++i) {
      for (int j = 0; j < (1 << W); ++j) {
        for (int k = 0; k < (1 << W); ++k) {
          ldp[i][j][k] = H * W + 1;
          udp[i][j][k] = -1;
        }
      }
    }
    int mask = (1 << W) - 1;
    for (int i = 0; i < (1 << W); ++i) {
      int r0 = interp(i, W), r1 = r0;
      for (int j = 0; j < (1 << W); ++j) {
        int r2 = interp(j, W), numBlack = __builtin_popcount(i);
        unsigned int c = 0;
        c += table[(r0 >> 0) & mask];
        c += table[(r0 >> 1) & mask];
        c += table[(r0 >> 2) & mask];
        c += table[(r1 >> 0) & mask];
        c += table[(r1 >> 1) & mask];
        c += table[(r1 >> 2) & mask];
        c += table[(r2 >> 0) & mask];
        c += table[(r2 >> 1) & mask];
        c += table[(r2 >> 2) & mask];
        c = ((c + 0x33333333) & 0x88888888) >> 3;
        if (c == table[image[0]]) {
          ldp[0][i][j] = udp[0][i][j] = numBlack;
        }
      }
    }
    for (int i = 1; i < H - 1; ++i) {
      for (int j0 = 0; j0 < (1 << W); ++j0) {
        int r0 = interp(j0, W);
        for (int j1 = 0; j1 < (1 << W); ++j1) {
          int r1 = interp(j1, W), numBlack = __builtin_popcount(j1);
          if (udp[i - 1][j0][j1] < 0) {
            continue;
          }
          for (int j2 = 0; j2 < (1 << W); ++j2) {
            int r2 = interp(j2, W);
            unsigned int c = 0;
            c += table[(r0 >> 0) & mask];
            c += table[(r0 >> 1) & mask];
            c += table[(r0 >> 2) & mask];
            c += table[(r1 >> 0) & mask];
            c += table[(r1 >> 1) & mask];
            c += table[(r1 >> 2) & mask];
            c += table[(r2 >> 0) & mask];
            c += table[(r2 >> 1) & mask];
            c += table[(r2 >> 2) & mask];
            c = ((c + 0x33333333) & 0x88888888) >> 3;
            if (c == table[image[i]]) {
              int lower = ldp[i - 1][j0][j1] + numBlack;
              int upper = udp[i - 1][j0][j1] + numBlack;
              ldp[i][j1][j2] = min(ldp[i][j1][j2], lower);
              udp[i][j1][j2] = max(udp[i][j1][j2], upper);
            }
          }
        }
      }
    }
    int minval = H * W + 1, maxval = -1;
    if (H == 1) {
      for (int i = 0; i < (1 << W); ++i) {
        minval = min(minval, ldp[0][i][i]);
        maxval = max(maxval, udp[0][i][i]);
      }
    } else {
      for (int i = 0; i < (1 << W); ++i) {
        int r0 = interp(i, W);
        for (int j = 0; j < (1 << W); ++j) {
          int r1 = interp(j, W), r2 = r1;
          if (udp[H - 2][i][j] < 0) {
            continue;
          }
          int numBlack = __builtin_popcount(j);
          unsigned int c = 0;
          c += table[(r0 >> 0) & mask];
          c += table[(r0 >> 1) & mask];
          c += table[(r0 >> 2) & mask];
          c += table[(r1 >> 0) & mask];
          c += table[(r1 >> 1) & mask];
          c += table[(r1 >> 2) & mask];
          c += table[(r2 >> 0) & mask];
          c += table[(r2 >> 1) & mask];
          c += table[(r2 >> 2) & mask];
          c = ((c + 0x33333333) & 0x88888888) >> 3;
          if (c == table[image[H - 1]]) {
            int lower = ldp[H - 2][i][j] + numBlack;
            int upper = udp[H - 2][i][j] + numBlack;
            minval = min(minval, lower);
            maxval = max(maxval, upper);
          }
        }
      }
    }
    cout << "Case " << caseNum++ << ": ";
    if (maxval < 0) {
      cout << "Impossible" << endl;
    } else {
      cout << maxval - minval << endl;
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

unsigned int table[256];
int ldp[8][1 << 8][1 << 8];
int udp[8][1 << 8][1 << 8];

int interp(int bits, int w) {
  bits = (bits << 1) | (bits & 1);
  return bits | ((bits & (1 << w)) << 1);
}

int main() {
  for (int i = 0; i < 256; ++i) {
    unsigned int x = 0;
    for (int j = 0; j < 8; ++j) {
      if (i & (1 << j)) {
        x |= (1 << (j * 4));
      }
    }
    table[i] = x;
  }
  int caseNum = 1;
  while (true) {
    int H, W;
    cin >> H >> W;
    if (H == 0 && W == 0) {
      break;
    }
    vector<string> simage(H);
    for (int i = 0; i < H; ++i) {
      cin >> simage[i];
    }
    vector<int> image(max(H, W));
    if (H >= W) {
      for (int i = 0; i < H; ++i) {
        for (int j = 0; j < W; ++j) {
          image[i] |= (simage[i][j] == '#') << j;
        }
      }
    } else {
      swap(H, W);
      for (int i = 0; i < W; ++i) {
        for (int j = 0; j < H; ++j) {
          image[j] |= (simage[i][j] == '#') << i;
        }
      }
    }
    for (int i = 0; i < H; ++i) {
      for (int j = 0; j < (1 << W); ++j) {
        for (int k = 0; k < (1 << W); ++k) {
          ldp[i][j][k] = H * W + 1;
          udp[i][j][k] = -1;
        }
      }
    }
    int mask = (1 << W) - 1;
    for (int i = 0; i < (1 << W); ++i) {
      int r0 = interp(i, W), r1 = r0;
      for (int j = 0; j < (1 << W); ++j) {
        int r2 = interp(j, W), numBlack = __builtin_popcount(i);
        unsigned int c = 0;
        c += table[(r0 >> 0) & mask];
        c += table[(r0 >> 1) & mask];
        c += table[(r0 >> 2) & mask];
        c += table[(r1 >> 0) & mask];
        c += table[(r1 >> 1) & mask];
        c += table[(r1 >> 2) & mask];
        c += table[(r2 >> 0) & mask];
        c += table[(r2 >> 1) & mask];
        c += table[(r2 >> 2) & mask];
        c = ((c + 0x33333333) & 0x88888888) >> 3;
        if (c == table[image[0]]) {
          ldp[0][i][j] = udp[0][i][j] = numBlack;
        }
      }
    }
    for (int i = 1; i < H - 1; ++i) {
      for (int j0 = 0; j0 < (1 << W); ++j0) {
        int r0 = interp(j0, W);
        for (int j1 = 0; j1 < (1 << W); ++j1) {
          int r1 = interp(j1, W), numBlack = __builtin_popcount(j1);
          if (udp[i - 1][j0][j1] < 0) {
            continue;
          }
          for (int j2 = 0; j2 < (1 << W); ++j2) {
            int r2 = interp(j2, W);
            unsigned int c = 0;
            c += table[(r0 >> 0) & mask];
            c += table[(r0 >> 1) & mask];
            c += table[(r0 >> 2) & mask];
            c += table[(r1 >> 0) & mask];
            c += table[(r1 >> 1) & mask];
            c += table[(r1 >> 2) & mask];
            c += table[(r2 >> 0) & mask];
            c += table[(r2 >> 1) & mask];
            c += table[(r2 >> 2) & mask];
            c = ((c + 0x33333333) & 0x88888888) >> 3;
            if (c == table[image[i]]) {
              int lower = ldp[i - 1][j0][j1] + numBlack;
              int upper = udp[i - 1][j0][j1] + numBlack;
              ldp[i][j1][j2] = min(ldp[i][j1][j2], lower);
              udp[i][j1][j2] = max(udp[i][j1][j2], upper);
            }
          }
        }
      }
    }
    int minval = H * W + 1, maxval = -1;
    if (H == 1) {
      for (int i = 0; i < (1 << W); ++i) {
        minval = min(minval, ldp[0][i][i]);
        maxval = max(maxval, ldp[0][i][i]);
      }
    } else {
      for (int i = 0; i < (1 << W); ++i) {
        int r0 = interp(i, W);
        for (int j = 0; j < (1 << W); ++j) {
          int r1 = interp(j, W), r2 = r1;
          if (udp[H - 2][i][j] < 0) {
            continue;
          }
          int numBlack = __builtin_popcount(j);
          unsigned int c = 0;
          c += table[(r0 >> 0) & mask];
          c += table[(r0 >> 1) & mask];
          c += table[(r0 >> 2) & mask];
          c += table[(r1 >> 0) & mask];
          c += table[(r1 >> 1) & mask];
          c += table[(r1 >> 2) & mask];
          c += table[(r2 >> 0) & mask];
          c += table[(r2 >> 1) & mask];
          c += table[(r2 >> 2) & mask];
          c = ((c + 0x33333333) & 0x88888888) >> 3;
          if (c == table[image[H - 1]]) {
            int lower = ldp[H - 2][i][j] + numBlack;
            int upper = udp[H - 2][i][j] + numBlack;
            minval = min(minval, lower);
            maxval = max(maxval, upper);
          }
        }
      }
    }
    cout << "Case " << caseNum++ << ": ";
    if (maxval < 0) {
      cout << "Impossible" << endl;
    } else {
      cout << maxval - minval << endl;
    }
  }
  return 0;
}