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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &a) {
  return os << "(" << a.first << ", " << a.second << ")";
};
template <class T> void pv(T a, T b) {
  for (T i = a; i != b; ++i)
    cerr << *i << " ";
  cerr << endl;
}
template <class T> bool chmin(T &t, const T &f) {
  if (t > f) {
    t = f;
    return true;
  }
  return false;
}
template <class T> bool chmax(T &t, const T &f) {
  if (t < f) {
    t = f;
    return true;
  }
  return false;
}

#include <chrono>
#include <memory>

// [0, 2^32)
unsigned xrand() {
  static unsigned x = 314159265, y = 358979323, z = 846264338, w = 327950288;
  unsigned t = x ^ x << 11;
  x = y;
  y = z;
  z = w;
  return w = w ^ w >> 19 ^ t ^ t >> 8;
}

// [a, b]
int xrand(int a, int b) { return a + xrand() % (b - a + 1); }

// [0.0, 1.0)
double xrandUniform() { return xrand() / 4294967296.0; }

constexpr double TIME_LIMIT = 1.9;
constexpr int D = 365;
constexpr int N = 26;

vector<int> C;
vector<vector<int>> S;

vector<int> ans;
int score;

void solve() {
  // const auto starter = chrono::high_resolution_clock::now();

#ifdef LOCAL
  constexpr int BEAM = 300;
#else
  constexpr int BEAM = 900;
#endif
  constexpr int WEIGHT = 3;

  const int CSum = accumulate(C.begin(), C.end(), 0);

  struct Cand {
    int score, grad;
    int prev;
    unique_ptr<vector<short>> last;
  };
  vector<vector<Cand>> dp(D + 1);
  dp[0].emplace_back(Cand{0, 0, -1, make_unique<vector<short>>(N, -1)});
  for (int d = 0; d < D; ++d) {
    const int len = dp[d].size();
    for (int h = 0; h < len; ++h) {
      const auto &c = dp[d][h];
      dp[d + 1].resize(dp[d].size() * N);
      for (int i = 0; i < N; ++i) {
        auto &cc = dp[d + 1][h * N + i];
        cc.grad = c.grad + (-CSum) - (-C[i] * (d - (*c.last)[i]));
        cc.score = c.score + cc.grad + S[d][i];
        cc.prev = h;
        cc.last = make_unique<vector<short>>(*c.last);
        (*cc.last)[i] = d;
      }
    }
    const int weight = (d == D - 1) ? 0 : WEIGHT;
    sort(dp[d + 1].begin(), dp[d + 1].end(),
         [&weight](const Cand &c0, const Cand &c1) {
           return (c0.score + weight * c0.grad > c1.score + weight * c1.grad);
         });
    if ((int)dp[d + 1].size() > BEAM) {
      dp[d + 1].resize(BEAM);
    }
  }

  ans.assign(D, -1);
  for (int d = D, h = 0; d > 0; --d) {
    for (int i = 0; i < N; ++i) {
      if ((*dp[d][h].last)[i] == d - 1) {
        ans[d - 1] = i;
        break;
      }
    }
    h = dp[d][h].prev;
  }
  score = dp[D][0].score;
}

void localTest(int numCases) {
  vector<Int> scores(numCases);
  for (int caseId = 0; caseId < numCases; ++caseId) {
    cerr << "localTest Case #" << caseId << endl;
    for (int i = 0; i < N; ++i) {
      C[i] = xrand(0, 100);
    }
    for (int d = 0; d < D; ++d)
      for (int i = 0; i < N; ++i) {
        S[d][i] = xrand(0, 20000);
      }
    solve();
    cerr << "localTest Case #" << caseId << ": " << score << endl;
    scores[caseId] = max(1'000'000 + score, 0);
  }
  cerr << "min score = " << *min_element(scores.begin(), scores.end()) << endl;
  cerr << "max score = " << *max_element(scores.begin(), scores.end()) << endl;
  cerr << "total score = " << accumulate(scores.begin(), scores.end(), 0LL)
       << endl;
}

int main() {
  C.resize(N);
  S.assign(D, vector<int>(N));

#ifdef LOCAL
  localTest(50);
#endif

  scanf("%*d");
  for (int i = 0; i < N; ++i) {
    scanf("%d", &C[i]);
  }
  for (int d = 0; d < D; ++d)
    for (int i = 0; i < N; ++i) {
      scanf("%d", &S[d][i]);
    }
  solve();
  for (int d = 0; d < D; ++d) {
    printf("%d\\n", ans[d] + 1);
  }
  cerr << "score = " << score << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &a) {
  return os << "(" << a.first << ", " << a.second << ")";
};
template <class T> void pv(T a, T b) {
  for (T i = a; i != b; ++i)
    cerr << *i << " ";
  cerr << endl;
}
template <class T> bool chmin(T &t, const T &f) {
  if (t > f) {
    t = f;
    return true;
  }
  return false;
}
template <class T> bool chmax(T &t, const T &f) {
  if (t < f) {
    t = f;
    return true;
  }
  return false;
}

#include <chrono>
#include <memory>

// [0, 2^32)
unsigned xrand() {
  static unsigned x = 314159265, y = 358979323, z = 846264338, w = 327950288;
  unsigned t = x ^ x << 11;
  x = y;
  y = z;
  z = w;
  return w = w ^ w >> 19 ^ t ^ t >> 8;
}

// [a, b]
int xrand(int a, int b) { return a + xrand() % (b - a + 1); }

// [0.0, 1.0)
double xrandUniform() { return xrand() / 4294967296.0; }

constexpr double TIME_LIMIT = 1.9;
constexpr int D = 365;
constexpr int N = 26;

vector<int> C;
vector<vector<int>> S;

vector<int> ans;
int score;

void solve() {
  // const auto starter = chrono::high_resolution_clock::now();

  constexpr int BEAM = 900;

  const int CSum = accumulate(C.begin(), C.end(), 0);

  struct Cand {
    int score, grad;
    int prev;
    unique_ptr<vector<short>> last;
  };
  vector<vector<Cand>> dp(D + 1);
  dp[0].emplace_back(Cand{0, 0, -1, make_unique<vector<short>>(N, -1)});
  for (int d = 0; d < D; ++d) {
    const int len = dp[d].size();
    for (int h = 0; h < len; ++h) {
      const auto &c = dp[d][h];
      dp[d + 1].resize(dp[d].size() * N);
      for (int i = 0; i < N; ++i) {
        auto &cc = dp[d + 1][h * N + i];
        cc.grad = c.grad + (-CSum) - (-C[i] * (d - (*c.last)[i]));
        cc.score = c.score + cc.grad + S[d][i];
        cc.prev = h;
        cc.last = make_unique<vector<short>>(*c.last);
        (*cc.last)[i] = d;
      }
    }
    const int weight = (d == D - 1) ? 0 : 3;
    sort(dp[d + 1].begin(), dp[d + 1].end(),
         [&weight](const Cand &c0, const Cand &c1) {
           return (c0.score + weight * c0.grad > c1.score + weight * c1.grad);
         });
    if ((int)dp[d + 1].size() > BEAM) {
      dp[d + 1].resize(BEAM);
    }
  }

  ans.assign(D, -1);
  for (int d = D, h = 0; d > 0; --d) {
    for (int i = 0; i < N; ++i) {
      if ((*dp[d][h].last)[i] == d - 1) {
        ans[d - 1] = i;
        break;
      }
    }
    h = dp[d][h].prev;
  }
  score = dp[D][0].score;
}

void localTest(int numCases) {
  vector<Int> scores(numCases);
  for (int caseId = 0; caseId < numCases; ++caseId) {
    cerr << "localTest Case #" << caseId << endl;
    for (int i = 0; i < N; ++i) {
      C[i] = xrand(0, 100);
    }
    for (int d = 0; d < D; ++d)
      for (int i = 0; i < N; ++i) {
        S[d][i] = xrand(0, 20000);
      }
    solve();
    cerr << "localTest Case #" << caseId << ": " << score << endl;
    scores[caseId] = max(1'000'000 + score, 0);
  }
  cerr << "min score = " << *min_element(scores.begin(), scores.end()) << endl;
  cerr << "max score = " << *max_element(scores.begin(), scores.end()) << endl;
  cerr << "total score = " << accumulate(scores.begin(), scores.end(), 0LL)
       << endl;
}

int main() {
  C.resize(N);
  S.assign(D, vector<int>(N));

  localTest(50);

  scanf("%*d");
  for (int i = 0; i < N; ++i) {
    scanf("%d", &C[i]);
  }
  for (int d = 0; d < D; ++d)
    for (int i = 0; i < N; ++i) {
      scanf("%d", &S[d][i]);
    }
  solve();
  for (int d = 0; d < D; ++d) {
    printf("%d\\n", ans[d] + 1);
  }
  cerr << "score = " << score << endl;

  return 0;
}