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

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

using ll = long long;

ll grid[3000][3000];
int R, C, K;

int dr[2] = {0, 1};
int dc[2] = {1, 0};
ll dp[3001][3001][4];

void solve() {
  dp[0][0][1] = grid[0][0];
  for (int r = 0; r < R; ++r) {
    for (int c = 0; c < C; ++c) {
      for (int k = 3; k >= 0; --k) {
        // cerr << r << " " << c << " " << k << " " << dp[r][c][k] << endl;
        for (int i = 0; i < 2; ++i) {
          int nr = r + dr[i];
          int nc = c + dc[i];
          if (nr >= R || nc >= C)
            continue;
          int nk = k;
          if (nr > r)
            nk = 0;
          dp[nr][nc][nk] = max(dp[nr][nc][nk], dp[r][c][k]);
          if (grid[nr][nc] > 0) {
            int nk = k + 1;
            if (nr > r)
              nk = 1;
            if (nk <= 3) {
              dp[nr][nc][nk] = max(dp[nr][nc][nk], dp[r][c][k] + grid[nr][nc]);
            }
          }
        }
      }
    }
  }
  ll ans = 0;
  for (int k = 0; k < 4; ++k) {
    ans = max(ans, dp[R - 1][C - 1][k]);
  }
  cout << ans << endl;
}

int main() {
  cin >> R >> C >> K;
  for (int i = 0; i < K; ++i) {
    int r, c, k;
    cin >> r >> c >> k;
    --r;
    --c;
    grid[r][c] = k;
  }
  // for (int i = 0; i < R; ++i) {
  //   for (int j = 0; j < C; ++j) {
  //     cout << grid[i][j];
  //   }
  //   cout << endl;
  // }
  solve();
}


Error: TLE

Fixed submission:

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

using ll = long long;

ll grid[3000][3000];
int R, C, K;

struct Move {
  ll sc = 0;
  int cnt = 0;
  int r = 0;
  int c = 0;
  Move() {}
  Move(ll sc, int cnt, int r, int c) : sc(sc), cnt(cnt), r(r), c(c) {}
  int id() { return r * 15000 + c * 5 + cnt; }
};

auto compare = [](Move &l, Move &r) {
  if ((l.r + l.c) == (r.r + r.c)) {
    if (l.sc == r.sc)
      return l.cnt > r.cnt;
    return l.sc < r.sc;
  }
  return (l.r + l.c) > (r.r + r.c);
};

int dr[2] = {0, 1};
int dc[2] = {1, 0};

void bfs() {
  ll ans = 0;
  priority_queue<Move, vector<Move>, decltype(compare)> pq{compare};
  pq.push({0, 0, 0, 0});
  if (grid[0][0] > 0) {
    pq.push({grid[0][0], 1, 0, 0});
  }
  unordered_map<int, ll> visit;
  int nv = 0;
  while (!pq.empty()) {
    Move m = pq.top();
    pq.pop();
    // cerr << m.r << " " << m.c << " " << m.cnt << " " << m.sc << endl;
    ans = max(ans, m.sc);
    if (visit[m.id()] > m.sc) {
      continue;
    }
    // if (m.r == R-1 && m.c == C-1) break;
    nv += 1;
    for (int i = 0; i < 2; ++i) {
      int nr = m.r + dr[i];
      int nc = m.c + dc[i];
      if (nr >= R || nc >= C)
        continue;
      {
        int cnt = m.cnt;
        if (nr > m.r)
          cnt = 0;
        Move nm = {m.sc, cnt, nr, nc};
        if (visit.find(nm.id()) == visit.end() || visit[nm.id()] < nm.sc) {
          pq.push(nm);
          visit[nm.id()] = nm.sc;
        }
      }
      if (grid[nr][nc] > 0) {
        int cnt = m.cnt;
        if (nr > m.r)
          cnt = 1;
        else {
          cnt += 1;
        }
        if (cnt <= 3) {
          Move nm = {m.sc + grid[nr][nc], cnt, nr, nc};
          if (visit.find(nm.id()) == visit.end() || visit[nm.id()] < nm.sc) {
            pq.push(nm);
            visit[nm.id()] = nm.sc;
          }
        }
      }
    }
  }
  cerr << nv << endl;
  cout << ans << endl;
}

int main() {
  cin >> R >> C >> K;
  for (int i = 0; i < K; ++i) {
    int r, c, k;
    cin >> r >> c >> k;
    --r;
    --c;
    grid[r][c] = k;
  }
  // for (int i = 0; i < R; ++i) {
  //   for (int j = 0; j < C; ++j) {
  //     cout << grid[i][j];
  //   }
  //   cout << endl;
  // }
  bfs();
}