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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 2010;
int n;
struct da {
  int v, id;
} q[maxn];
long long dp[maxn][maxn];
inline bool cmp(da aa, da bb) { return aa.v > bb.v; }
long long dfs(int l, int r) {
  if (dp[l][r] != -1)
    return dp[l][r];
  if (l > r)
    return 0;
  da now = q[l + n - r];
  dp[l][r] = max(dp[l][r], dfs(l, r - 1) + 1ll * now.v * abs(r - now.id));
  dp[l][r] = max(dp[l][r], dfs(l + 1, r) + 1ll * now.v * abs(l - now.id));
  return dp[l][r];
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    scanf("%d", &q[i].v), q[i].id = i;
  sort(q + 1, q + n + 1, cmp);
  memset(dp, -1, sizeof dp);
  printf("%lld\\n", dfs(1, n));
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const long long INF = 1e18;
const long long t = 1e14;
const int maxd = int(8e6) + 11;
const int maxe = int(8e6) + 11;
int tot = 0;
int head[maxd]; //-1
int S, T;

struct Edge {
  int from, to, cap;
  long long cost;
  int next;
  Edge() {}
  Edge(int x, int y, int a, long long b, int c)
      : from(x), to(y), cap(a), cost(b), next(c) {}
} eage[maxe * 2];

void add(int x, int y, int a, long long b) {
  eage[tot] = Edge(x, y, a, b, head[x]), head[x] = tot++;
  eage[tot] = Edge(y, x, 0, -b, head[y]), head[y] = tot++;
  return;
}

bool used[maxd], vis[maxd];
long long dis[maxd];
queue<int> que;
long long ans = 0;

bool spfa() {
  for (int i = 0; i < T + 100; i++)
    used[i] = false, dis[i] = INF, vis[i] = false;
  while (que.size())
    que.pop();

  que.push(S);
  used[S] = true;
  dis[S] = 0;

  while (que.size()) {
    int u = que.front();
    que.pop();
    used[u] = false;
    for (int i = head[u]; ~i; i = eage[i].next)
      if (eage[i].cap && dis[eage[i].to] > dis[u] + eage[i].cost) {
        int v = eage[i].to;
        dis[v] = dis[u] + eage[i].cost;
        if (!used[v]) {
          used[v] = true;
          que.push(v);
        }
      }
  }
  return (dis[T] < INF); // max  -> 0
}

int dfs(int u, int flow) {
  if (u == T) {
    ans += dis[u] * flow;
    return flow;
  }
  vis[u] = true;
  int ret = 0;
  for (int i = head[u]; ~i; i = eage[i].next)
    if (!vis[eage[i].to] && eage[i].cap &&
        dis[eage[i].to] == dis[u] + eage[i].cost) {
      int v = eage[i].to;
      int newf = dfs(v, min(flow, eage[i].cap));
      eage[i].cap -= newf;
      eage[i ^ 1].cap += newf;
      ret += newf;
      flow -= newf;
      if (!flow)
        break;
    }
  if (!ret)
    dis[u] = -1;
  return ret;
}

long long MCMF() {
  ans = 0;
  while (spfa())
    dfs(S, 1e9);
  return ans;
}
int n;
int main() {
  memset(head, -1, sizeof head);
  scanf("%d", &n);
  S = 2 * n + 1;
  T = 2 * n + 2;
  for (int i = 1; i <= n; i++)
    add(S, i, 1, 0), add(n + i, T, 1, 0);
  for (int i = 1; i <= n; i++) {
    long long x;
    scanf("%lld", &x);
    for (int j = 1; j <= min(50, i); j++) {
      long long now = x * abs(i - j);
      add(i, n + j, 1, -now + t);
    }
    for (int j = n; j >= max(n - 50, i); j--) {
      long long now = x * abs(i - j);
      add(i, n + j, 1, -now + t);
    }
    for (int j = i; j >= max(i - 50, 1); j--) {
      long long now = x * abs(i - j);
      add(i, n + j, 1, -now + t);
    }
    for (int j = i; j <= min(i + 50, n); j++) {
      long long now = x * abs(i - j);
      add(i, n + j, 1, -now + t);
    }
  }
  printf("%lld\\n", -(MCMF() - 1ll * n * t));
  return 0;
}