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

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define uint unsigned int
#define ull unsigned long long
#define pb push_back
#define mk make_pair
#define ins insert
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define X first
#define Y second
#define umap unordered_map
#define speed()                                                                \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0)
#define setvalue(d, s, e, n)                                                   \\
  for (int qwe = s; qwe < e; ++qwe)                                            \\
  d[qwe] = n
#define mset multiset
#define pqueue priority_queue

template <class T>
using oset =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

const int N = 3e3 + 12;
const int INF = 1e9;
const double PI = acos(-1);
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const long long LINF = 1e18 + 3141;
ll a[N][N];
ll dp[N][N][4];
int n, m, k;

void maxself(ll &a, ll c) { a = max(a, c); }
ll get(int x, int y, int t) {
  if (t < 0)
    return 0;
  if (x <= 0 || x > n || y > m || y <= 0)
    return 0;
  if (dp[x][y][t] != -1)
    return dp[x][y][t];

  assert(false);

  return -1;
  // if(t == 0) {
  //     ll fromUp = get(x - 1, y, 0);
  //     maxself(fromUp, get(x - 1, y, 1));
  //     maxself(fromUp, get(x - 1, y, 2));
  //     maxself(fromUp, get(x - 1, y, 3));
  //     ll fromLeft = get(x, y - 1, 0);
  //     return dp[x][y][t] = max(fromLeft, fromUp);
  // }
  // ll fromUp = 0;
  // if(a[x][y] && t == 1) {
  //     fromUp = get(x - 1, y, 0);
  //     maxself(fromUp, get(x - 1, y, 1));
  //     maxself(fromUp, get(x - 1, y, 2));
  //     maxself(fromUp, get(x - 1, y, 3));
  //     fromUp += a[x][y];
  // }
  // // dont take
  // ll fromLeft = get(x, y - 1, t);
  // maxself(fromLeft, get(x, y - 1, t - 1) + a[x][y]);

  // return dp[x][y][t] = max(fromLeft, fromUp);
}
void solve() {
  cin >> n >> m >> k;
  while (k--) {
    int x, y, v;
    cin >> x >> y >> v;
    a[x][y] = v;
  }
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j)
      for (int t = 0; t <= 3; ++t)
        dp[i][j][t] = -1;

  for (int x = 1; x <= n; ++x) {
    for (int y = 1; y <= m; ++y) {
      for (int t = 0; t <= 3; ++t) {
        if (t == 0) {
          ll fromUp = get(x - 1, y, 0);
          maxself(fromUp, get(x - 1, y, 1));
          maxself(fromUp, get(x - 1, y, 2));
          maxself(fromUp, get(x - 1, y, 3));
          ll fromLeft = get(x, y - 1, 0);
          dp[x][y][t] = max(fromLeft, fromUp);
        } else {
          ll fromUp = 0;
          if (a[x][y] && t == 1) {
            fromUp = get(x - 1, y, 0);
            maxself(fromUp, get(x - 1, y, 1));
            maxself(fromUp, get(x - 1, y, 2));
            maxself(fromUp, get(x - 1, y, 3));
            fromUp += a[x][y];
          }
          // dont take
          ll fromLeft = get(x, y - 1, t);
          if (t - 1 >= 0)
            maxself(fromLeft, get(x, y - 1, t - 1) + a[x][y]);
          dp[x][y][t] = max(fromUp, fromLeft);
        }
      }
    }
  }

  // dp[x][y][t]  -> dp[x][y][t]  x row took k items
  //
  // dp[n][m][3] ->   dp[]
  // for(int i = 1; i <= n; ++i) {
  //     for(int j = 1; j <= m; ++j) {
  //         if(a[i][j]) {
  //             for(int k = 1; k <= 3; ++k) {
  //                 maxself(dp[i + 1][j][0], dp[i][j][k - 1] + a[i][j]);
  //                 maxself(dp[i][j + 1][k], dp[i][j][k - 1] + a[i][j]);
  //             }
  //         }
  //         for(int k = 0; k <= 3; ++k) {
  //             maxself(dp[i + 1][j][0], dp[i][j][k]);
  //             maxself(dp[i][j + 1][k], dp[i][j][k]);
  //         }
  //     }
  // }
  ll mx = 0;
  for (int i = 0; i <= 3; ++i) {
    mx = max(mx, get(n, m, i));
  }
  cout << mx;
}

int main() {
  // speed();
  int t = 1;
  // cin >> t;
  while (t--)
    solve();
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define uint unsigned int
#define ull unsigned long long
#define pb push_back
#define mk make_pair
#define ins insert
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define X first
#define Y second
#define umap unordered_map
#define speed()                                                                \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0)
#define setvalue(d, s, e, n)                                                   \\
  for (int qwe = s; qwe < e; ++qwe)                                            \\
  d[qwe] = n
#define mset multiset
#define pqueue priority_queue

template <class T>
using oset =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

const int N = 3e3 + 12;
const int INF = 1e9;
const double PI = acos(-1);
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const long long LINF = 1e18 + 3141;
ll a[N][N];
ll dp[N][N][4];
int n, m, k;

void maxself(ll &a, ll c) { a = max(a, c); }
ll get(int x, int y, int t) {
  if (t < 0)
    return -LINF;
  if (x < 0 || x > n || y > m || y < 0)
    return -LINF;
  if (dp[x][y][t])
    return dp[x][y][t];
  if (t == 0) {
    ll fromUp = get(x - 1, y, 0);
    maxself(fromUp, get(x - 1, y, 1));
    maxself(fromUp, get(x - 1, y, 2));
    maxself(fromUp, get(x - 1, y, 3));
    ll fromLeft = get(x, y - 1, 0);
    return dp[x][y][t] = max(fromLeft, fromUp);
  }
  ll fromUp = 0;
  if (a[x][y] && t == 1) {
    fromUp = get(x - 1, y, 0);
    maxself(fromUp, get(x - 1, y, 1));
    maxself(fromUp, get(x - 1, y, 2));
    maxself(fromUp, get(x - 1, y, 3));
    fromUp += a[x][y];
  }
  // dont take
  ll fromLeft = get(x, y - 1, t);
  maxself(fromLeft, get(x, y - 1, t - 1) + a[x][y]);

  return dp[x][y][t] = max(fromLeft, fromUp);
}
void solve() {
  cin >> n >> m >> k;
  while (k--) {
    int x, y, v;
    cin >> x >> y >> v;
    a[x][y] = v;
  }
  // dp[x][y][t]  -> dp[x][y][t]  x row took k items
  //
  // dp[n][m][3] ->   dp[]
  // for(int i = 1; i <= n; ++i) {
  //     for(int j = 1; j <= m; ++j) {
  //         if(a[i][j]) {
  //             for(int k = 1; k <= 3; ++k) {
  //                 maxself(dp[i + 1][j][0], dp[i][j][k - 1] + a[i][j]);
  //                 maxself(dp[i][j + 1][k], dp[i][j][k - 1] + a[i][j]);
  //             }
  //         }
  //         for(int k = 0; k <= 3; ++k) {
  //             maxself(dp[i + 1][j][0], dp[i][j][k]);
  //             maxself(dp[i][j + 1][k], dp[i][j][k]);
  //         }
  //     }
  // }
  ll mx = 0;
  for (int i = 0; i <= 3; ++i) {
    mx = max(mx, get(n, m, i));
  }
  cout << mx;
}

int main() {
  speed();
  int t = 1;
  // cin >> t;
  while (t--)
    solve();
}