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

#include <bits/stdc++.h>
using namespace std;
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define _repl(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define _rep(i, n) _repl(i, 0, n)
#define rep(...) GET_MACRO(__VA_ARGS__, _repl, _rep)(__VA_ARGS__)
#define mp(a, b) make_pair((a), (b))
#define pb(a) push_back((a))
#define all(x) (x).begin(), (x).end()
#define uniq(x) sort(all(x)), (x).erase(unique(all(x)), end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
void _dbg(string) { cout << endl; }
template <class H, class... T> void _dbg(string s, H h, T... t) {
  int l = s.find(',');
  cout << s.substr(0, l) << " = " << h << ", ";
  _dbg(s.substr(l + 1), t...);
}
template <class T, class U>
ostream &operator<<(ostream &o, const pair<T, U> &p) {
  o << "(" << p.fi << "," << p.se << ")";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const vector<T> &v) {
  o << "[";
  for (T t : v) {
    o << t << ",";
  }
  o << "]";
  return o;
}

#define INF 1120000000
#define long long long // for codeforces

int node[1000][26];
int type[1000][26];
int nodes = 0;

string word[100];
int score[100];

char m[6][6];
bool visited[6][6];

inline int init_node() {
  rep(i, 26) node[nodes][i] = -1;
  rep(i, 26) type[nodes][i] = -1;
  return nodes++;
}

void build_trie(int idx, int l, int node_id) {
  if (word[idx].size() == l + 1) {
    type[node_id][word[idx].back() - 'A'] = idx;
    return;
  }
  int c = word[idx][l] - 'A';
  // dbg(idx,l,node_id,word[idx]);
  assert(0 <= c && c < 26);
  if (node[node_id][c] == -1)
    node[node_id][c] = init_node();
  build_trie(idx, l + 1, node[node_id][c]);
}

int cnt[111];

void dfs(int x, int y, int node_id, int dep) {
  int c = m[x][y] - 'A';
  if (type[node_id][c] >= 0)
    cnt[type[node_id][c]]++;

  visited[x][y] = true;
  int nid = node[node_id][c];
  if (nid >= 0) {
    rep(dx, -1, 2) rep(dy, -1, 2) {
      int nx = x + dx, ny = y + dy;
      if (visited[nx][ny] || m[nx][ny] == '\\0')
        continue;
      if (nid >= 0)
        dfs(nx, ny, nid, dep + 1);
    }
  }
  visited[x][y] = false;
}

int main() {
  int n;
  cin >> n;
  rep(i, n) cin >> word[i] >> score[i];

  init_node();
  rep(i, n) build_trie(i, 0, 0);

  fill(m[0], m[6], '\\0');
  fill(visited[0], visited[6], false);
  rep(i, 4) scanf("%s", &m[i + 1][1]);

  fill(cnt, cnt + n, 0);
  rep(i, 1, 5) rep(j, 1, 5) dfs(i, j, 0, 1);

  int t;
  cin >> t;
  vector<int> dp(t + 1, 0);
  rep(i, n) {
    vector<int> nxt(dp);
    int sz = word[i].size();
    for (int j = 1; sz * j <= t && j <= cnt[i]; j++) {
      int c = sz * j;
      int v = score[i] * j;
      for (int k = t - c; k >= 0; k--) {
        nxt[k + c] = max(nxt[k + c], dp[k] + v);
      }
    }
    swap(dp, nxt);
  }

  cout << *max_element(all(dp)) << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define _repl(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define _rep(i, n) _repl(i, 0, n)
#define rep(...) GET_MACRO(__VA_ARGS__, _repl, _rep)(__VA_ARGS__)
#define mp(a, b) make_pair((a), (b))
#define pb(a) push_back((a))
#define all(x) (x).begin(), (x).end()
#define uniq(x) sort(all(x)), (x).erase(unique(all(x)), end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
void _dbg(string) { cout << endl; }
template <class H, class... T> void _dbg(string s, H h, T... t) {
  int l = s.find(',');
  cout << s.substr(0, l) << " = " << h << ", ";
  _dbg(s.substr(l + 1), t...);
}
template <class T, class U>
ostream &operator<<(ostream &o, const pair<T, U> &p) {
  o << "(" << p.fi << "," << p.se << ")";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const vector<T> &v) {
  o << "[";
  for (T t : v) {
    o << t << ",";
  }
  o << "]";
  return o;
}

#define INF 1120000000
#define long long long // for codeforces

int node[1000][26];
int point[1000][26];
int nodes = 0;

string word[100];
int score[100];

char m[6][6];
bool visited[6][6];

inline int init_node() {
  rep(i, 26) node[nodes][i] = -1;
  return nodes++;
}

void build_trie(int idx, int l, int node_id) {
  if (word[idx].size() == l + 1) {
    point[node_id][word[idx].back() - 'A'] = score[idx];
    return;
  }
  int c = word[idx][l] - 'A';
  // dbg(idx,l,node_id,word[idx]);
  assert(0 <= c && c < 26);
  if (node[node_id][c] == -1)
    node[node_id][c] = init_node();
  build_trie(idx, l + 1, node[node_id][c]);
}

vector<pair<int, int>> vec;
// time, score
void dfs(int x, int y, int node_id, int dep) {
  int c = m[x][y] - 'A';
  if (point[node_id][c])
    vec.pb(mp(dep, point[node_id][c]));

  visited[x][y] = true;
  int nid = node[node_id][c];
  if (nid >= 0) {
    rep(dx, -1, 2) rep(dy, -1, 2) {
      int nx = x + dx, ny = y + dy;
      if (visited[nx][ny] || m[nx][ny] == '\\0')
        continue;
      if (nid >= 0)
        dfs(nx, ny, nid, dep + 1);
    }
  }
  visited[x][y] = false;
}

int main() {
  int n;
  cin >> n;
  rep(i, n) cin >> word[i] >> score[i];

  fill(point[0], point[n], 0);
  init_node();
  rep(i, n) build_trie(i, 0, 0);

  fill(m[0], m[6], '\\0');
  fill(visited[0], visited[6], false);
  rep(i, 4) scanf("%s", &m[i + 1][1]);

  rep(i, 1, 5) rep(j, 1, 5) dfs(i, j, 0, 1);
  // dbg(vec);
  int t;
  cin >> t;
  vector<long> dp(t + 1, 0);
  for (auto &p : vec) {
    int c = p.first;
    int v = p.second;
    for (int i = t - c; i >= 0; i--) {
      dp[i + c] = max(dp[i + c], dp[i] + v);
    }
  }

  cout << *max_element(all(dp)) << endl;

  return 0;
}