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

// {{{
// vim:filetype=cpp foldmethod=marker foldmarker={{{,}}}
#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define ALL(A) (A).begin(), (A).end()
#define DUMP(A) cout << #A << "=" << (A) << endl
#define SIZE(A) (int)((A).size())
#define MP make_pair
#define PB push_back
using namespace std;
typedef long long ll;

int vx[] = {1, 0, -1, 0}, vy[] = {0, 1, 0, -1};
// }}}

int field[1000][1000];
int dp[1000][1000];
int main() {
  for (;;) {
    int H, W, N;
    scanf("%d%d%d", &H, &W, &N);
    if (H == 0 && W == 0 && N == 0)
      break;
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        scanf("%d", &field[i][j]);
      }
    }
    dp[0][0] = N - 1;
    for (int i = 1; i < H; i++) {
      if (field[i - 1][0] == 0)
        dp[i][0] = (dp[i - 1][0] + 1) / 2;
      else
        dp[i][0] = dp[i - 1][0] / 2;
    }
    for (int i = 1; i < W; i++) {
      if (field[0][i - 1] == 1)
        dp[0][i] = (dp[0][i - 1] + 1) / 2;
      else
        dp[0][i] = dp[0][i - 1] / 2;
    }
    for (int i = 1; i < H; i++) {
      for (int j = 1; j < W; j++) {
        dp[i][j] = 0;
        if (field[i - 1][j] == 0)
          dp[i][j] += (dp[i - 1][j] + 1) / 2;
        else
          dp[i][j] += dp[i - 1][j] / 2;
        if (field[i][j - 1] == 1)
          dp[i][j] += (dp[i][j - 1] + 1) / 2;
        else
          dp[i][j] += dp[i][j - 1] / 2;
      }
    }
    int nx = 0, ny = 0;
    while (nx < H && ny < W) {
      if ((dp[nx][ny] + field[nx][ny]) % 2 == 1)
        ny++;
      else
        nx++;
    }
    printf("%d %d\\n", nx + 1, ny + 1);
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
int main() {
  int H, W, N;
  for (;;) {
    scanf("%d%d%d", &H, &W, &N);
    if (H == 0 && W == 0 && N == 0)
      break;
    vector<vector<int>> fst(H, vector<int>(W));
    vector<vector<vector<int>>> gotime(
        H + 1, vector<vector<int>>(W + 1, vector<int>()));
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        scanf("%d", &fst[i][j]);
      }
    }
    gotime[0][0].push_back(0);
    for (int i = 0; i <= H; i++) {
      for (int j = 0; j <= W; j++) {
        if (i > 0 && j < W) {
          int sz = gotime[i - 1][j].size();
          if (sz % 2 == 0) {
            for (int k = fst[i - 1][j]; k < sz; k += 2) {
              gotime[i][j].push_back(gotime[i - 1][j][k]);
              if (i - 1 + j < 32 &&
                  gotime[i - 1][j][k] + (1 << (i - 1 + j)) <= 10000000) {
                gotime[i][j].push_back(gotime[i - 1][j][k] +
                                       (1 << (i - 1 + j)));
              }
            }
          } else {
            for (int k = fst[i - 1][j]; k < sz; k += 2) {
              gotime[i][j].push_back(gotime[i - 1][j][k]);
            }
            for (int k = (fst[i - 1][j] + 1) % 2; k < sz; k += 2) {
              if (i - 1 + j < 32 &&
                  gotime[i - 1][j][k] + (1 << (i - 1 + j)) <= 10000000) {
                gotime[i][j].push_back(gotime[i - 1][j][k] +
                                       (1 << (i - 1 + j)));
              }
            }
          }
        }
        if (j > 0 && i < H) {
          int sz = gotime[i][j - 1].size();
          if (sz % 2 == 0) {
            for (int k = (fst[i][j - 1] + 1) % 2; k < sz; k += 2) {
              gotime[i][j].push_back(gotime[i][j - 1][k]);
              if (i + j - 1 < 32 &&
                  gotime[i][j - 1][k] + (1 << (i + j - 1)) <= 10000000) {
                gotime[i][j].push_back(gotime[i][j - 1][k] +
                                       (1 << (i + j - 1)));
              }
            }
          } else {
            for (int k = (fst[i][j - 1] + 1) % 2; k < sz; k += 2) {
              gotime[i][j].push_back(gotime[i][j - 1][k]);
            }
            for (int k = fst[i][j - 1]; k < sz; k += 2) {
              if (i + j - 1 < 32 &&
                  gotime[i][j - 1][k] + (1 << (i + j - 1)) <= 10000000) {
                gotime[i][j].push_back(gotime[i][j - 1][k] +
                                       (1 << (i + j - 1)));
              }
            }
          }
        }
        sort(gotime[i][j].begin(), gotime[i][j].end());
      }
    }
    N--;
    for (int i = 0; i <= H; i++) {
      int nn = N;
      if (i + W < 32)
        nn %= (1 << (i + W));
      if (binary_search(gotime[i][W].begin(), gotime[i][W].end(), nn)) {
        printf("%d %d\\n", i + 1, W + 1);
      }
    }
    for (int j = 0; j < W; j++) {
      int nn = N;
      if (j + H < 32)
        nn %= (1 << (j + H));
      if (binary_search(gotime[H][j].begin(), gotime[H][j].end(), nn)) {
        printf("%d %d\\n", H + 1, j + 1);
      }
    }
  }
}