Problem p02839 (C++)

Buggy submission (status: Runtime Error):
// https://atcoder.jp/contests/abc147/tasks/abc147_e

#include <bits/stdc++.h>

using namespace std;

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, b, e) for (int i = (b); i <= (int)(e); i++)
#define DUMP(a, n) REP(_i, n) printf("%d%c", a[_i], _i + 1 == n ? '\n' : ' ')
#define DUMP2D(a, n, m)                                                        \
  REP(_i, n) REP(_j, m) printf("%d%c", a[_i][_j], _j + 1 == m ? '\n' : ' ');   \
  puts("")

const int H_MAX = 80;
const int W_MAX = 80;
const int A_IJ_MAX = 80;
const int B_IJ_MAX = 80;
const int BS_SIZE = 6400;

int H, W;
int A[H_MAX][W_MAX];
int B[H_MAX][W_MAX];

bitset<BS_SIZE> dp0[W_MAX];
bitset<BS_SIZE> dp1[W_MAX];
bitset<BS_SIZE> wk;

bitset<BS_SIZE> &move_bs(bitset<BS_SIZE> &bs, int v) {
  wk.reset();
  REP(i, BS_SIZE) if (bs[i]) {
    wk.set(i + v);
    wk.set(abs(i - v));
  }
  return wk;
}

void solve() {
  auto cur = dp0;
  auto nxt = dp1;
  REP(i, H) {
    REP(j, W) {
      nxt[j].reset();
      int v = abs(A[i][j] - B[i][j]);
      if (i == 0 && j == 0)
        nxt[j].set(v);
      if (i > 0)
        nxt[j] |= move_bs(cur[j], v);
      if (j > 0)
        nxt[j] |= move_bs(nxt[j - 1], v);
      // printf("[%d, %d] ", i, j);
      // REP(k, BS_SIZE) if (nxt[j][k]) printf("%d,", k);
      // puts("");
    }
    swap(cur, nxt);
  }
  REP(i, BS_SIZE) {
    if (cur[W - 1][i]) {
      printf("%d\n", i);
      return;
    }
  }
}

void input() {
  scanf("%d%d", &H, &W);
  REP(i, H) REP(j, W) scanf("%d", &A[i][j]);
  REP(i, H) REP(j, W) scanf("%d", &B[i][j]);
}

int main() {
  input();
  solve();
  return 0;
}


Fixed submission:
// https://atcoder.jp/contests/abc147/tasks/abc147_e

#include <bits/stdc++.h>

using namespace std;

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, b, e) for (int i = (b); i <= (int)(e); i++)
#define DUMP(a, n) REP(_i, n) printf("%d%c", a[_i], _i + 1 == n ? '\n' : ' ')
#define DUMP2D(a, n, m)                                                        \
  REP(_i, n) REP(_j, m) printf("%d%c", a[_i][_j], _j + 1 == m ? '\n' : ' ');   \
  puts("")

const int H_MAX = 80;
const int W_MAX = 80;
const int A_IJ_MAX = 80;
const int B_IJ_MAX = 80;
const int BS_SIZE = 6400;

int H, W;
int A[H_MAX][W_MAX];
int B[H_MAX][W_MAX];

bitset<BS_SIZE> dp0[W_MAX];
bitset<BS_SIZE> dp1[W_MAX];
bitset<BS_SIZE> wk;

bitset<BS_SIZE> &move_bs(bitset<BS_SIZE> &bs, int v) {
  wk.reset();
  REP(i, BS_SIZE) if (bs[i]) {
    if (i + v < BS_SIZE)
      wk.set(i + v);
    if (abs(i - v) < BS_SIZE)
      wk.set(abs(i - v));
  }
  return wk;
}

void solve() {
  auto cur = dp0;
  auto nxt = dp1;
  REP(i, H) {
    REP(j, W) {
      nxt[j].reset();
      int v = abs(A[i][j] - B[i][j]);
      if (i == 0 && j == 0)
        nxt[j].set(v);
      if (i > 0)
        nxt[j] |= move_bs(cur[j], v);
      if (j > 0)
        nxt[j] |= move_bs(nxt[j - 1], v);
      // printf("[%d, %d] ", i, j);
      // REP(k, BS_SIZE) if (nxt[j][k]) printf("%d,", k);
      // puts("");
    }
    swap(cur, nxt);
  }
  REP(i, BS_SIZE) {
    if (cur[W - 1][i]) {
      printf("%d\n", i);
      return;
    }
  }
}

void input() {
  scanf("%d%d", &H, &W);
  REP(i, H) REP(j, W) scanf("%d", &A[i][j]);
  REP(i, H) REP(j, W) scanf("%d", &B[i][j]);
}

int main() {
  input();
  solve();
  return 0;
}