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

#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

template <class T> inline void chmax(T &a, const T &b) {
  if (b > a)
    a = b;
}

constexpr int SIZE = 4;
constexpr int MAX_N = 100;
constexpr int MAX_LEN = 8;

const int dx[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
const int dy[8] = {-1, -1, -1, 0, 0, 1, 1, 1};

unordered_map<string, int> word_idx;

string board[SIZE];
int scores[MAX_N];
int cnt[MAX_N];
int len[MAX_N];
bool visited[SIZE][SIZE];

void dfs(int x, int y, string s = "") {
  s += board[y][x];
  if (word_idx.count(s))
    ++cnt[word_idx[s]];
  if (s.size() >= MAX_LEN)
    return;

  visited[y][x] = true;

  for (int i = 0; i < 8; ++i) {
    const int nx = x + dx[i];
    const int ny = y + dy[i];

    if (nx < 0 || ny < 0 || nx >= SIZE || ny >= SIZE || visited[ny][nx])
      continue;

    dfs(nx, ny, s);
  }

  visited[y][x] = false;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n;
  cin >> n;

  for (int i = 0; i < n; ++i) {
    string word;
    cin >> word >> scores[i];
    word_idx[word] = i;
    len[i] = (int)word.size();
  }

  for (int i = 0; i < SIZE; ++i) {
    cin >> board[i];
  }

  int t;
  cin >> t;

  memset(visited, false, sizeof(visited));
  for (int i = 0; i < SIZE; ++i) {
    for (int j = 0; j < SIZE; ++j) {
      dfs(j, i);
    }
  }

  vector<int> dp(t + 1, 0);
  for (int i = 0; i < n; ++i) {
    int num = cnt[i];
    for (int j = 1; num > 0; j <<= 1) {
      const int mul = min(j, num);
      const int sum_len = len[i] * mul;
      const int sum_score = scores[i] * mul;
      for (int k = t - sum_len; k >= 0; --k) {
        chmax(dp[k + sum_len], dp[k] + sum_score);
      }
      num -= mul;
    }
  }

  cout << *max_element(dp.begin(), dp.end()) << endl;

  return EXIT_SUCCESS;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

template <class T> inline void chmax(T &a, const T &b) {
  if (b > a)
    a = b;
}

constexpr int SIZE = 4;
constexpr int MAX_N = 100;
constexpr int MAX_LEN = 8;

const int dx[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
const int dy[8] = {-1, -1, -1, 0, 0, 1, 1, 1};

unordered_map<string, int> word_idx;

string board[SIZE];
int scores[MAX_N];
int cnt[MAX_N];
int len[MAX_N];
bool visited[SIZE][SIZE];

void dfs(int x, int y, string s = "") {
  s += board[y][x];
  if (word_idx.count(s))
    ++cnt[word_idx[s]];
  if (s.size() >= MAX_LEN)
    return;

  visited[y][x] = true;

  for (int i = 0; i < 8; ++i) {
    const int nx = x + dx[i];
    const int ny = y + dy[i];

    if (nx < 0 || ny < 0 || nx >= SIZE || ny >= SIZE || visited[ny][nx])
      continue;

    dfs(nx, ny, s);
  }

  visited[y][x] = false;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n;
  cin >> n;

  for (int i = 0; i < n; ++i) {
    string word;
    cin >> word >> scores[i];
    word_idx[word] = i;
    len[i] = (int)word.size();
  }

  for (int i = 0; i < SIZE; ++i) {
    cin >> board[i];
  }

  int t;
  cin >> t;

  memset(visited, false, sizeof(visited));
  for (int i = 0; i < SIZE; ++i) {
    for (int j = 0; j < SIZE; ++j) {
      dfs(j, i);
    }
  }

  vector<int> dp(t + 1, 0);
  int mx = 0;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < cnt[i]; ++j) {
      for (int k = min(mx, t - len[i]); k >= 0; --k) {
        chmax(dp[k + len[i]], dp[k] + scores[i]);
      }
      mx += len[i];
    }
  }

  cout << *max_element(dp.begin(), dp.end()) << endl;

  return EXIT_SUCCESS;
}