Problem p03960 (C++)

Buggy submission (status: Runtime Error):
#pragma gcc optimize("Ofast")

#include "bits/stdc++.h"
using namespace std;
typedef int64_t lld;
typedef pair<int, int> pii;
typedef pair<lld, lld> pll;
typedef pair<int, pll> pip;
typedef pair<pll, int> ppi;
typedef pair<lld, pll> plp;
typedef pair<pll, lld> ppl;
typedef pair<pll, pll> ppp;
template <typename T> using maxHeap = priority_queue<T, vector<T>, less<T>>;
template <typename T> using minHeap = priority_queue<T, vector<T>, greater<T>>;
#define ff first
#define ss second
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define endl '\n'
#define jizz                                                                   \
  cin.tie(0);                                                                  \
  cout.tie(0);                                                                 \
  ios::sync_with_stdio(0);
inline void input(int &_x) {
  _x = 0;
  int _tmp = 1;
  char _tc = getchar();
  while ((_tc < '0' || _tc > '9') && _tc != '-')
    _tc = getchar();
  if (_tc == '-')
    _tc = getchar(), _tmp = -1;
  while (_tc >= '0' && _tc <= '9')
    _x = _x * 10 + (_tc - 48), _tc = getchar();
  _x *= _tmp;
}
inline void output(int _x) {
  char _buff[20];
  int _f = 0;
  if (_x == 0)
    putchar('0');
  while (_x > 0) {
    _buff[_f++] = _x % 10 + '0';
    _x /= 10;
  }
  for (_f -= 1; _f >= 0; _f--)
    putchar(_buff[_f]);
  putchar('\n');
}
template <typename Iter> ostream &_out(ostream &s, Iter b, Iter e) {
  s << "[";
  for (auto it = b; it != e; it++)
    s << (it == b ? "" : " ") << *it;
  s << "]";
  return s;
}
template <class T1, class T2>
ostream &operator<<(ostream &out, pair<T1, T2> p) {
  return out << '(' << p.first << ", " << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &s, const vector<T> &c) {
  return _out(s, c.begin(), c.end());
}
#ifdef erd1
#define pprint(x)                                                              \
  cerr << __PRETTY_FUNCTION__ << ":" << __LINE__ << " - " << (#x) << "="       \
       << (x) << endl
#else
#define pprint(x)
#endif

// code starts here
const int N = 300;
int dp[N + 2][N + 2] = {}, rep[N * 2][N + 2] = {};
vector<string> v;
signed main() {
  int h, w;
  cin >> h >> w;
  for (int i = 0; i < h; i++) {
    string s;
    cin >> s;
    v.pb(s);
  }
  for (int i = 0; i < h; i++)
    dp[h + 1][i] = dp[i][h + 1] = 2000000000;
  int ans = 0;
  for (int i = 0; i < w - 1; i++) {
    for (int diff = -h + 1; diff < h; diff++) {
      for (int j = max(diff, 0); j < h + min(diff, 0); j++) {
        rep[diff + h][j + 1] =
            rep[diff + h][j] + (v[j][i] == v[j - diff][i + 1]);
        // assert(rep[diff+h][j+1] < INT_MAX-2000000000);
      }
    }
    for (int l = h; l >= 0; l--) {
      for (int r = h; r >= 0; r--) {
        dp[l][r] = min(dp[l + 1][r] + rep[l + 1 - r + h][l + 1],
                       dp[l][r + 1] + rep[l - r - 1 + h][l]);
        assert(rep[l + 1 - r + h][l + 1] < INT_MAX - 2000000000);
        assert(rep[l - r - 1 + h][l] < INT_MAX - 2000000000);
        // assert(dp[l][r] < 2000000000);
      }
    }
    ans += dp[0][0];
  }

  cout << ans << endl;
}


Fixed submission:
#pragma gcc optimize("Ofast")

#include "bits/stdc++.h"
using namespace std;
typedef int64_t lld;
typedef pair<int, int> pii;
typedef pair<lld, lld> pll;
typedef pair<int, pll> pip;
typedef pair<pll, int> ppi;
typedef pair<lld, pll> plp;
typedef pair<pll, lld> ppl;
typedef pair<pll, pll> ppp;
template <typename T> using maxHeap = priority_queue<T, vector<T>, less<T>>;
template <typename T> using minHeap = priority_queue<T, vector<T>, greater<T>>;
#define ff first
#define ss second
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define endl '\n'
#define jizz                                                                   \
  cin.tie(0);                                                                  \
  cout.tie(0);                                                                 \
  ios::sync_with_stdio(0);
inline void input(int &_x) {
  _x = 0;
  int _tmp = 1;
  char _tc = getchar();
  while ((_tc < '0' || _tc > '9') && _tc != '-')
    _tc = getchar();
  if (_tc == '-')
    _tc = getchar(), _tmp = -1;
  while (_tc >= '0' && _tc <= '9')
    _x = _x * 10 + (_tc - 48), _tc = getchar();
  _x *= _tmp;
}
inline void output(int _x) {
  char _buff[20];
  int _f = 0;
  if (_x == 0)
    putchar('0');
  while (_x > 0) {
    _buff[_f++] = _x % 10 + '0';
    _x /= 10;
  }
  for (_f -= 1; _f >= 0; _f--)
    putchar(_buff[_f]);
  putchar('\n');
}
template <typename Iter> ostream &_out(ostream &s, Iter b, Iter e) {
  s << "[";
  for (auto it = b; it != e; it++)
    s << (it == b ? "" : " ") << *it;
  s << "]";
  return s;
}
template <class T1, class T2>
ostream &operator<<(ostream &out, pair<T1, T2> p) {
  return out << '(' << p.first << ", " << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &s, const vector<T> &c) {
  return _out(s, c.begin(), c.end());
}
#ifdef erd1
#define pprint(x)                                                              \
  cerr << __PRETTY_FUNCTION__ << ":" << __LINE__ << " - " << (#x) << "="       \
       << (x) << endl
#else
#define pprint(x)
#endif

// code starts here
const int N = 300;
int dp[N + 2][N + 2] = {}, rep[N * 2 + 2][N + 2] = {};
vector<string> v;
signed main() {
  int h, w;
  cin >> h >> w;
  for (int i = 0; i < h; i++) {
    string s;
    cin >> s;
    v.pb(s);
  }
  for (int i = 0; i < h; i++)
    dp[h + 1][i] = dp[i][h + 1] = 2000000000;
  int ans = 0;
  for (int i = 0; i < w - 1; i++) {
    for (int diff = -h + 1; diff < h; diff++) {
      for (int j = max(diff, 0); j < h + min(diff, 0); j++) {
        rep[diff + h][j + 1] =
            rep[diff + h][j] + (v[j][i] == v[j - diff][i + 1]);
        // assert(rep[diff+h][j+1] < INT_MAX-2000000000);
      }
    }
    for (int l = h; l >= 0; l--) {
      for (int r = h; r >= 0; r--) {
        dp[l][r] = min(dp[l + 1][r] + rep[l + 1 - r + h][l + 1],
                       dp[l][r + 1] + rep[l - r - 1 + h][l]);
        assert(rep[l + 1 - r + h][l + 1] < INT_MAX - 2000000000);
        assert(rep[l - r - 1 + h][l] < INT_MAX - 2000000000);
        // assert(dp[l][r] < 2000000000);
      }
    }
    ans += dp[0][0];
  }

  cout << ans << endl;
}