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

// 区間dp
#include <bits/stdc++.h>
#define REP(i, n) for (long long i = 0; i < (n); i++)
#define FOR(i, a, b) for (long long i = (a); i < (b); i++)
#define RREP(i, n) for (long long i = n; i >= 0; i--)
#define RFOR(i, a, b) for (long long i = (a); i > (b); i--)
#define dump1d_arr(array)                                                      \\
  REP(i, array.size())                                                         \\
      cerr << #array << "[" << (i) << "] ==> " << (array[i]) << endl
#define dump2d_arr(array)                                                      \\
  REP(i, array.size())                                                         \\
      REP(j, array[i].size()) cerr << #array << "[" << (i) << "]"              \\
                                   << "[" << (j) << "] ==> " << (array[i][j])  \\
                                   << endl
#define dump(x) cerr << #x << " => " << (x) << endl
#define dumpP(p) cerr << "( " << p.first << " , " << p.second << " )" << ends
#define SORT(c) sort((c).begin(), (c).end())
#define MIN(vec) *min_element(vec.begin(), vec.end())
#define MAX(vec) *max_element(vec.begin(), vec.end())
#define UNIQ(vec)                                                              \\
  vec.erase(unique(vec.begin(), vec.end()), vec.end()) // ソートの必要あり
#define IN(n, m) (!(m.find(n) == m.end()))
#define ENUM(m) for (auto itr = m.begin(); itr != m.end(); ++itr)
#define dump_MAP(m)                                                            \\
  for (auto itr = m.begin(); itr != m.end(); ++itr) {                          \\
    cerr << itr->first << " --> " << itr->second << endl;                      \\
  }
#define FINDL(vec, x) (lower_bound(vec.begin(), vec.end(), x) - vec.begin())
#define FINDU(vec, x) (upper_bound(vec.begin(), vec.end(), x) - vec.begin())
#define ROUND(N) setprecision(N)
#define ROUND_PRINT(N, val)                                                    \\
  cout << fixed;                                                               \\
  cout << setprecision(N) << val << endl
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define INARR(h, w, x, y) (0 <= y && y < h && 0 <= x && x < w)
#define EQ(a, b) (abs(a - b) < 1e-10)
using namespace std;
constexpr int dx[4] = {0, 1, 0, -1};
constexpr int dy[4] = {1, 0, -1, 0};
constexpr long double pi = M_PI;
constexpr double eps = 1e-10;
constexpr long mod = 1000000007;
constexpr short shINF = 32767;
constexpr long loINF = 2147483647;
constexpr long long llINF = 9223372036854775807;
typedef long long LL;
typedef vector<long> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<LL, LL> pr;
typedef vector<bool> VB;
typedef vector<VB> VVB;
typedef vector<pr> VP;
struct Order {
  bool operator()(pr const &a, pr const &b) const {
    return a.first > b.first || ((a.first == b.first) && (a.second > b.second));
  }
};

VVI dp;
VI w;
int n;

int dfs(int l, int r) {
  if (dp[l][r] != loINF)
    return dp[l][r];
  int width = (r - l) + 1;
  if (width == 2) {
    if (abs(w[l] - w[r]) <= 1)
      return 2;
    else
      return 0;
  }
  if (width == 4) {
    int ans = dfs(l, l + 1) + dfs(l + 2, r);
    int ans2 = dfs(l + 1, l + 2);
    if (ans2 == 2 && abs(w[l] - w[r]) <= 1)
      ans2 += 2;
    return dp[l][r] = max(ans, ans2);
  }

  int ans = 0;
  int ans2 = dfs(l + 1, r - 1);
  if (ans2 == width - 2 && abs(w[l] - w[r]) <= 1)
    ans2 += 2;
  else {
    for (int i = (l + 1); i <= (r - 2); i += 2) {
      ans = max(ans, dfs(l, i) + dfs(i + 1, r));
      if (ans == width)
        break;
    }
  }
  return dp[l][r] = max(ans, ans2);
}

int main(void) {
  while (1) {
    cin >> n;
    if (n == 0)
      break;
    w.resize(n);
    dp = VVI(n, VI(n, loINF));
    REP(i, n) { cin >> w[i]; }
    if (n % 2)
      cout << max(dfs(1, n - 1), dfs(0, n - 2)) << endl;
    else
      cout << dfs(0, n - 1) << endl;
    // dump2d_arr(dp);
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define REP(i, n) for (long long i = 0; i < (n); i++)
#define FOR(i, a, b) for (long long i = (a); i < (b); i++)
#define RREP(i, n) for (long long i = n; i >= 0; i--)
#define RFOR(i, a, b) for (long long i = (a); i > (b); i--)
#define dump1d_arr(array)                                                      \\
  REP(i, array.size())                                                         \\
      cerr << #array << "[" << (i) << "] ==> " << (array[i]) << endl
#define dump2d_arr(array)                                                      \\
  REP(i, array.size())                                                         \\
      REP(j, array[i].size()) cerr << #array << "[" << (i) << "]"              \\
                                   << "[" << (j) << "] ==> " << (array[i][j])  \\
                                   << endl
#define dump(x) cerr << #x << " => " << (x) << endl
#define dumpP(p) cerr << "( " << p.first << " , " << p.second << " )" << ends
#define SORT(c) sort((c).begin(), (c).end())
#define MIN(vec) *min_element(vec.begin(), vec.end())
#define MAX(vec) *max_element(vec.begin(), vec.end())
#define UNIQ(vec)                                                              \\
  vec.erase(unique(vec.begin(), vec.end()), vec.end()) // ソートの必要あり
#define IN(n, m) (!(m.find(n) == m.end()))
#define ENUM(m) for (auto itr = m.begin(); itr != m.end(); ++itr)
#define dump_MAP(m)                                                            \\
  for (auto itr = m.begin(); itr != m.end(); ++itr) {                          \\
    cerr << itr->first << " --> " << itr->second << endl;                      \\
  }
#define FINDL(vec, x) (lower_bound(vec.begin(), vec.end(), x) - vec.begin())
#define FINDU(vec, x) (upper_bound(vec.begin(), vec.end(), x) - vec.begin())
#define ROUND(N) setprecision(N)
#define ROUND_PRINT(N, val)                                                    \\
  cout << fixed;                                                               \\
  cout << setprecision(N) << val << endl
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define INARR(h, w, x, y) (0 <= y && y < h && 0 <= x && x < w)
#define EQ(a, b) (abs(a - b) < 1e-10)
using namespace std;
constexpr int dx[4] = {0, 1, 0, -1};
constexpr int dy[4] = {1, 0, -1, 0};
constexpr long double pi = M_PI;
constexpr double eps = 1e-10;
constexpr long mod = 1000000007;
constexpr short shINF = 32767;
constexpr long loINF = 2147483647;
constexpr long long llINF = 9223372036854775807;
typedef long long LL;
typedef vector<LL> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<LL, LL> pr;
typedef vector<bool> VB;
typedef vector<pr> VP;
struct Order {
  bool operator()(pr const &a, pr const &b) const {
    return a.first > b.first || ((a.first == b.first) && (a.second > b.second));
  }
};
int n;
vector<int> w;
typedef bitset<301> bit;
struct Comp {
  bool operator()(const bit &a, const bit &b) {
    for (int i = 300 - 1; i >= 0; i--) {
      if (a[i] ^ b[i])
        return b[i];
    }
    return false;
  }
};
map<bit, int, Comp> memo;
int dfs(bit &state) {
  if (IN(state, memo))
    return memo[state];
  int num = 0, fi;
  REP(i, n - 1) {
    if ((!state[i])) {
      fi = i;
      break;
    }
  }
  FOR(i, fi + 1, n) {
    if (!state[i]) {
      if (abs(w[i] - w[fi]) <= 1) {
        state.set(i);
        state.set(fi);
        num = max(dfs(state) + 2, num);
        state.reset(i);
        state.reset(fi);
      }
      fi = i;
    }
  }
  return memo[state] = num;
}

int main(void) {
  while (1) {
    cin >> n;
    if (n == 0)
      break;
    w.resize(n);
    REP(i, n) { cin >> w[i]; }
    bit state(0);
    cout << dfs(state) << endl;
    memo.clear();
  }
}