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

#include <bits/stdc++.h>
using namespace std;
constexpr int time_limit = 1900;
chrono::system_clock::time_point start, current;
int c[26];
int64_t s[366][26];

int64_t eval(const vector<int> &state, int d) {
  int last[26] = {0};
  int64_t csum = 0;
  for (int i = 0; i < 26; ++i)
    csum += c[i];
  int64_t decl = -csum;
  int64_t score = 0;

  for (int i = 1; i <= d; ++i) {
    score += s[i][state[i]];
    decl += (i - last[state[i]]) * c[state[i]];
    last[state[i]] = i;
    score += decl;
    decl -= csum;
  }
  return score;
}

struct simulated_annealing {
  random_device dev;
  mt19937_64 rng;
  uniform_real_distribution<double> dist;
  uniform_int_distribution<int> typ;
  int D;

  simulated_annealing(int d) : dist{0.0, 1.0}, typ{0, 25}, D(d) {
    rng.seed(dev());
  }

  vector<int> loop() {
    vector<int> state, best_state;
    state.resize(D + 1);
    best_state.resize(D + 1);
    for (int i = 1; i <= D; ++i)
      state[i] = best_state[i] = typ(rng);
    int64_t curr_score = eval(state, D), best_score = curr_score;

    for (int iter = 1;; ++iter) {
      current = chrono::system_clock::now();
      if (chrono::duration_cast<chrono::milliseconds>(current - start)
              .count() >= time_limit)
        break;
      auto next_state = neighbor(state);
      int64_t next_score = eval(next_state, D);

      if (next_score >= curr_score ||
          dist(rng) <= probability(curr_score, next_score, temperature(iter))) {
        curr_score = next_score;
        state = next_state;
        if (best_score < curr_score) {
          best_score = curr_score;
          best_state = state;
        }
      }
    }
    return best_state;
  }
  vector<int> neighbor(const vector<int> &curr) {
    vector<int> ret{curr};
    int x = rand() % D + 1;
    ret[x] = typ(rng);
    return ret;
  }
  double probability(double score1, double score2, double t) {
    if (score1 <= score2)
      return 1.0;
    else
      return exp((score2 - score1) / t);
  }
  double temperature(int step) { return pow(0.99, step); }
};

int main() {
  start = chrono::system_clock::now();
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout.precision(12);
  cout.setf(ios_base::fixed, ios_base::floatfield);

  int d;
  cin >> d;
  for (int i = 0; i < 26; ++i)
    cin >> c[i];
  for (int i = 1; i <= d; ++i) {
    for (int j = 0; j < 26; ++j)
      cin >> s[i][j];
  }
  simulated_annealing sa(d);
  auto ans = sa.loop();

  for (int i = 1; i <= d; ++i)
    cout << ans[i] + 1 << endl;
  cerr << eval(ans, d) << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
constexpr int time_limit = 2000;
chrono::system_clock::time_point start, current;
int c[26];
int64_t s[366][26];

int64_t eval(const vector<int> &state, int d) {
  int last[26] = {0};
  int64_t csum = 0;
  for (int i = 0; i < 26; ++i)
    csum += c[i];
  int64_t decl = -csum;
  int64_t score = 0;

  for (int i = 1; i <= d; ++i) {
    score += s[i][state[i]];
    decl += (i - last[state[i]]) * c[state[i]];
    last[state[i]] = i;
    score += decl;
    decl -= csum;
  }
  return score;
}

struct simulated_annealing {
  random_device dev;
  mt19937_64 rng;
  uniform_real_distribution<double> dist;
  uniform_int_distribution<int> typ;
  int D;

  simulated_annealing(int d) : dist{0.0, 1.0}, typ{0, 25}, D(d) {
    rng.seed(dev());
  }

  vector<int> loop() {
    vector<int> state, best_state;
    state.resize(D + 1);
    best_state.resize(D + 1);
    for (int i = 1; i <= D; ++i)
      state[i] = best_state[i] = typ(rng);
    int64_t curr_score = eval(state, D), best_score = curr_score;

    for (int iter = 1;; ++iter) {
      current = chrono::system_clock::now();
      if (chrono::duration_cast<chrono::milliseconds>(current - start)
              .count() >= time_limit)
        break;
      auto next_state = neighbor(state);
      int64_t next_score = eval(next_state, D);

      if (next_score >= curr_score ||
          dist(rng) <= probability(curr_score, next_score, temperature(iter))) {
        curr_score = next_score;
        state = next_state;
        if (best_score < curr_score) {
          best_score = curr_score;
          best_state = state;
        }
      }
    }
    return best_state;
  }
  vector<int> neighbor(const vector<int> &curr) {
    vector<int> ret{curr};
    int x = rand() % D + 1;
    ret[x] = typ(rng);
    return ret;
  }
  double probability(double score1, double score2, double t) {
    if (score1 <= score2)
      return 1.0;
    else
      return exp((score2 - score1) / t);
  }
  double temperature(int step) { return pow(0.99, step); }
};

int main() {
  start = chrono::system_clock::now();
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout.precision(12);
  cout.setf(ios_base::fixed, ios_base::floatfield);

  int d;
  cin >> d;
  for (int i = 0; i < 26; ++i)
    cin >> c[i];
  for (int i = 1; i <= d; ++i) {
    for (int j = 0; j < 26; ++j)
      cin >> s[i][j];
  }
  simulated_annealing sa(d);
  auto ans = sa.loop();

  for (int i = 1; i <= d; ++i)
    cout << ans[i] << endl;

  return 0;
}