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

#include <bits/stdc++.h>

using namespace std;

namespace {

typedef double real;
typedef long long ll;

template <class K, class V>
ostream &operator<<(ostream &os, const pair<K, V> &p) {
  return os << "(" << p.first << "," << p.second << ")";
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &vs) {
  if (vs.empty())
    return os << "[]";
  os << "[" << vs[0];
  for (int i = 1; i < vs.size(); i++)
    os << " " << vs[i];
  return os << "]";
}
template <class T> istream &operator>>(istream &is, vector<T> &vs) {
  for (auto it = vs.begin(); it != vs.end(); it++)
    is >> *it;
  return is;
}

int N;
vector<string> ws;
vector<int> ss;
int T;
vector<string> F;
void input() {
  cin >> N;
  ws.clear();
  ws.resize(N);
  ss.clear();
  ss.resize(N);
  for (int i = 0; i < N; i++)
    cin >> ws[i] >> ss[i];
  F.clear();
  F.resize(4);
  cin >> F;
  cin >> T;
}

vector<int> count;

void dfs(int i, int j, int y, int x, int used) {
  if (j == ws[i].size()) {
    count[i]++;
    return;
  }
  for (int dy = -1; dy <= 1; dy++) {
    for (int dx = -1; dx <= 1; dx++) {
      if (dy == 0 && dx == 0)
        continue;
      int ny = y + dy;
      int nx = x + dx;
      if (ny < 0 || ny >= 4 || nx < 0 || nx >= 4)
        continue;
      if (F[ny][nx] != ws[i][j])
        continue;
      if (used & (1 << (4 * ny + nx)))
        continue;
      dfs(i, j + 1, ny, nx, used | (1 << 4 * ny + nx));
    }
  }
}

const int INF = 1 << 28;

void solve() {
  count.clear();
  count.resize(N, 0);
  map<char, bool> found;
  for (int y = 0; y < 4; y++) {
    for (int x = 0; x < 4; x++) {
      found[F[y][x]] = true;
    }
  }
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < ws[i].size(); j++) {
      if (not found[ws[i][j]]) {
        goto next;
      }
    }
    for (int y = 0; y < 4; y++) {
      for (int x = 0; x < 4; x++) {
        if (F[y][x] == ws[i][0]) {
          dfs(i, 1, y, x, 1 << (4 * y + x));
        }
      }
    }
  next:;
  }
  auto dp = vector<vector<int>>(2, vector<int>(T + 1, -INF));
  dp[0][0] = 0;
  for (int i = 1; i <= N; i++) {
    int l = ws[i - 1].size();
    for (int t = 0; t <= T; t++) {
      if (dp[0][t] >= 0) {
        for (int k = 0; k <= count[i - 1]; k++) {
          int x = t + k * l;
          if (x > T)
            break;
          dp[1][x] = max(dp[1][x], dp[0][t] + k * ss[i - 1]);
        }
      }
    }
    swap(dp[0], dp[1]);
  }
  int ans = 0;
  for (int t = 0; t <= T; t++) {
    ans = max(ans, dp[0][t]);
  }
  cout << ans << endl;
}
} // namespace

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

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

namespace {

typedef double real;
typedef long long ll;

template <class K, class V>
ostream &operator<<(ostream &os, const pair<K, V> &p) {
  return os << "(" << p.first << "," << p.second << ")";
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &vs) {
  if (vs.empty())
    return os << "[]";
  os << "[" << vs[0];
  for (int i = 1; i < vs.size(); i++)
    os << " " << vs[i];
  return os << "]";
}
template <class T> istream &operator>>(istream &is, vector<T> &vs) {
  for (auto it = vs.begin(); it != vs.end(); it++)
    is >> *it;
  return is;
}

int N;
vector<string> ws;
vector<int> ss;
int T;
vector<string> F;
void input() {
  cin >> N;
  ws.clear();
  ws.resize(N);
  ss.clear();
  ss.resize(N);
  for (int i = 0; i < N; i++)
    cin >> ws[i] >> ss[i];
  F.clear();
  F.resize(4);
  cin >> F;
  cin >> T;
}

vector<int> count;

void dfs(int i, int j, int y, int x, int used) {
  if (j == ws[i].size()) {
    count[i]++;
    return;
  }
  for (int dy = -1; dy <= 1; dy++) {
    for (int dx = -1; dx <= 1; dx++) {
      if (dy == 0 && dx == 0)
        continue;
      int ny = y + dy;
      int nx = x + dx;
      if (ny < 0 || ny >= 4 || nx < 0 || nx >= 4)
        continue;
      if (F[ny][nx] != ws[i][j])
        continue;
      if (used & (1 << (4 * ny + nx)))
        continue;
      dfs(i, j + 1, ny, nx, used | (1 << 4 * ny + nx));
    }
  }
}

const int INF = 1 << 28;

void solve() {
  count.clear();
  count.resize(N, 0);
  for (int i = 0; i < N; i++) {
    for (int y = 0; y < 4; y++) {
      for (int x = 0; x < 4; x++) {
        if (F[y][x] == ws[i][0]) {
          dfs(i, 1, y, x, 1 << (4 * y + x));
        }
      }
    }
  }
  auto dp = vector<vector<int>>(2, vector<int>(T + 1, -INF));
  dp[0][0] = 0;
  for (int i = 1; i <= N; i++) {
    int l = ws[i - 1].size();
    for (int t = 0; t <= T; t++) {
      if (dp[0][t] >= 0) {
        for (int k = 0; k <= count[i - 1]; k++) {
          int x = t + k * l;
          if (x <= T) {
            dp[1][x] = max(dp[1][x], dp[0][t] + k * ss[i - 1]);
          }
        }
      }
    }
    swap(dp[0], dp[1]);
  }
  int ans = 0;
  for (int t = 0; t <= T; t++) {
    ans = max(ans, dp[0][t]);
  }
  cout << ans << endl;
}
} // namespace

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