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

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
#define INF 1e9

static const int seed = 6;
static const int D = 365;
static const int ntype = 26;
static const int population_size = 100;
int gene[population_size][D + 1];
int next_gene[population_size][D + 1];
static int elete[D + 1];
static long long elete_score = -INF;
static const int init_n_greedyGene = 1;
static double crossRate = 0.7;
static double mutationRate = 0.3;
static double elete_select_prob = 0.05;
static const double after_crossRate = 0.8;
static const double after_mutationRate = 0.9;
static const double after_elete_select_prob = 0.05;
static const int n_mutation_p = 300;
vector<pair<double, int>> cumfreq;

// Info
int change_time = 0;
int crossover_time = 0;
int mutation_time = 0;
int total_cross = 0;
int different_cross = 0;
int change_elete = 0;

void Info() {
  cout << "change: " << change_time << endl;
  cout << "crossover: " << crossover_time << endl;
  cout << "mutation: " << mutation_time << endl;
  cout << "total_cross: " << total_cross << endl;
  cout << "different_cross: " << different_cross << endl;
  cout << "elete_score: " << elete_score << endl;
  cout << "change_elete: " << change_elete << endl;
}

class Contest {
public:
  Contest() { last = 0; }
  int s[D + 1];
  int c;
  int last;
};

Contest contest[ntype + 1];

void Input() {
  int d;
  cin >> d;
  for (int i = 1; i <= ntype; ++i) {
    int t;
    cin >> t;
    contest[i].c = t;
  }
  for (int day = 1; day <= D; ++day) {
    for (int type = 1; type <= ntype; ++type) {
      int t;
      cin >> t;
      contest[type].s[day] = t;
    }
  }
}

void randGene(int p) {
  for (int day = 1; day <= D; ++day) {
    gene[p][day] = rand() % ntype + 1;
  }
}

void greedyGene(int p) {
  vector<int> l(ntype + 1, 0);
  long long score = 0;
  for (int d = 1; d <= D; ++d) {
    for (int i = 1; i <= ntype; ++i)
      score -= contest[i].c * (d - l[i]);
    long long temp = score;
    int t = -1;
    for (int i = 1; i <= ntype; ++i) {
      long long k = contest[i].s[d] + contest[i].c * (d - l[i]) + score;
      if (k > temp) {
        temp = k;
        t = i;
      }
    }
    gene[p][d] = t;
    l[t] = d;
  }
}

int evaluate(int i) {
  int v[D + 1];
  v[0] = 0;
  vector<int> l(ntype + 1, 0);
  for (int day = 1; day <= D; ++day) {
    v[day] = v[day - 1];
    int type = gene[i][day];
    v[day] += contest[type].s[day];
    l[type] = day;
    for (int t = 1; t <= ntype; ++t) {
      v[day] -= contest[t].c * (day - l[t]);
    }
  }
  return v[D];
}

void calcCumFreq() {
  int n = cumfreq.size();
  sort(cumfreq.begin(), cumfreq.end());
  // change elete
  ++change_elete;
  if (elete_score < (int)cumfreq[n - 1].first) {
    ++change_time;
    elete_score = (int)cumfreq[n - 1].first;
    int i = cumfreq[n - 1].second;
    for (int d = 1; d <= D; ++d)
      elete[d] = gene[i][d];
  }
  double cprob = 1 - elete_select_prob;
  double cn = n * (n - 1) / 2.0;
  cprob /= cn;
  for (int i = 0; i < n - 1; ++i) {
    cumfreq[i].first = cprob;
  }
  cumfreq[n - 1].first = elete_select_prob;
  for (int i = 0; i < n - 1; ++i) {
    cumfreq[i + 1].first += cumfreq[i].first;
  }
}

void CrossOver(int gene_i, int ci, int cj) {
  ++crossover_time;
  for (int d = 1; d <= D; ++d)
    next_gene[gene_i][d] = gene[ci][d];
  int p = rand() % D + 1;
  /*

  change

  */
  ++total_cross;
  if (next_gene[gene_i][p] != gene[cj][p]) {
    ++different_cross;
    /*
        cout<<ci<<" "<<cj<<endl;
        cout<<"from: "<<next_gene[gene_i][p]<<" to: "<<gene[cj][p]<<endl;;
    */
    next_gene[gene_i][p] = gene[cj][p];
  }
}

void Mutation(int ngene_i) {
  ++mutation_time;
  for (int i = 0; i < n_mutation_p; ++i) {
    int p = rand() % D + 1;
    next_gene[ngene_i][p] = rand() % ntype + 1;
  }
}

int Select() {
  double a = (double)rand() / RAND_MAX;
  int t = cumfreq.size() - 1;
  for (int i = 0; i < t; ++i) {
    if (cumfreq[i + 1].first > a)
      return cumfreq[i].second;
  }
  return cumfreq[t].second;
}

void Init(int nGreedy) {
  for (int i = 0; i < nGreedy; ++i) {
    greedyGene(i);
  }
  for (int i = nGreedy; i < population_size; ++i) {
    randGene(i);
  }
}

void makeCumFreq() {
  for (int i = 0; i < population_size; ++i) {
    double e = (double)evaluate(i);
    cumfreq.push_back(make_pair(e, i));
  }
  calcCumFreq();
}

void makeNextGeneration() {
  for (int d = 1; d <= D; ++d)
    next_gene[0][d] = elete[d];
  for (int i = 1; i < population_size; ++i) {
    int pi = Select();
    double crossrand = (double)rand() / RAND_MAX;
    if (crossrand < crossRate) {
      int pj = Select();
      while (pi == pj)
        pj = Select();
      CrossOver(i, pi, pj);
    } else {
      for (int j = 1; j <= D; ++j)
        next_gene[i][j] = gene[pi][j];
    }
    double murand = (double)rand() / RAND_MAX;
    if (murand < mutationRate) {
      Mutation(i);
    }
  }
  for (int i = 0; i < 50; ++i) {
    for (int j = 1; j <= D; ++j) {
      gene[i][j] = next_gene[i][j];
    }
  }
}

void GA(int n) {
  for (int i = 0; i < n; ++i) {
    makeCumFreq();
    makeNextGeneration();
    cumfreq.resize(0);
  }
}

void Output() {
  for (int d = 1; d <= D; ++d)
    cout << elete[d] << endl;
}

int main() {
  srand(seed);
  Input();
  Init(1);
  GA(1000);
  Output();
  // Info();
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
#define INF 1e9

static const int seed = 6;
static const int D = 365;
static const int ntype = 26;
static const int population_size = 100;
int gene[population_size][D + 1];
int next_gene[population_size][D + 1];
static int elete[D + 1];
static long long elete_score = -INF;
static const int init_n_greedyGene = 1;
static double crossRate = 0.7;
static double mutationRate = 0.3;
static double elete_select_prob = 0.05;
static const double after_crossRate = 0.8;
static const double after_mutationRate = 0.9;
static const double after_elete_select_prob = 0.05;
static const int n_mutation_p = 300;
vector<pair<double, int>> cumfreq;

// Info
int change_time = 0;
int crossover_time = 0;
int mutation_time = 0;
int total_cross = 0;
int different_cross = 0;
int change_elete = 0;

void Info() {
  cout << "change: " << change_time << endl;
  cout << "crossover: " << crossover_time << endl;
  cout << "mutation: " << mutation_time << endl;
  cout << "total_cross: " << total_cross << endl;
  cout << "different_cross: " << different_cross << endl;
  cout << "elete_score: " << elete_score << endl;
  cout << "change_elete: " << change_elete << endl;
}

class Contest {
public:
  Contest() { last = 0; }
  int s[D + 1];
  int c;
  int last;
};

Contest contest[ntype + 1];

void Input() {
  int d;
  cin >> d;
  for (int i = 1; i <= ntype; ++i) {
    int t;
    cin >> t;
    contest[i].c = t;
  }
  for (int day = 1; day <= D; ++day) {
    for (int type = 1; type <= ntype; ++type) {
      int t;
      cin >> t;
      contest[type].s[day] = t;
    }
  }
}

void randGene(int p) {
  for (int day = 1; day <= D; ++day) {
    gene[p][day] = rand() % ntype + 1;
  }
}

void greedyGene(int p) {
  vector<int> l(ntype + 1, 0);
  long long score = 0;
  for (int d = 1; d <= D; ++d) {
    for (int i = 1; i <= ntype; ++i)
      score -= contest[i].c * (d - l[i]);
    long long temp = score;
    int t = -1;
    for (int i = 1; i <= ntype; ++i) {
      long long k = contest[i].s[d] + contest[i].c * (d - l[i]) + score;
      if (k > temp) {
        temp = k;
        t = i;
      }
    }
    gene[p][d] = t;
    l[t] = d;
  }
}

int evaluate(int i) {
  int v[D + 1];
  v[0] = 0;
  vector<int> l(ntype + 1, 0);
  for (int day = 1; day <= D; ++day) {
    v[day] = v[day - 1];
    int type = gene[i][day];
    v[day] += contest[type].s[day];
    l[type] = day;
    for (int t = 1; t <= ntype; ++t) {
      v[day] -= contest[t].c * (day - l[t]);
    }
  }
  return v[D];
}

void calcCumFreq() {
  int n = cumfreq.size();
  sort(cumfreq.begin(), cumfreq.end());
  // change elete
  ++change_elete;
  if (elete_score < (int)cumfreq[n - 1].first) {
    ++change_time;
    elete_score = (int)cumfreq[n - 1].first;
    int i = cumfreq[n - 1].second;
    for (int d = 1; d <= D; ++d)
      elete[d] = gene[i][d];
  }
  double cprob = 1 - elete_select_prob;
  double cn = n * (n - 1) / 2.0;
  cprob /= cn;
  for (int i = 0; i < n - 1; ++i) {
    cumfreq[i].first = cprob;
  }
  cumfreq[n - 1].first = elete_select_prob;
  for (int i = 0; i < n - 1; ++i) {
    cumfreq[i + 1].first += cumfreq[i].first;
  }
}

void CrossOver(int gene_i, int ci, int cj) {
  ++crossover_time;
  for (int d = 1; d <= D; ++d)
    next_gene[gene_i][d] = gene[ci][d];
  int p = rand() % D + 1;
  /*

  change

  */
  ++total_cross;
  if (next_gene[gene_i][p] != gene[cj][p]) {
    ++different_cross;
    /*
        cout<<ci<<" "<<cj<<endl;
        cout<<"from: "<<next_gene[gene_i][p]<<" to: "<<gene[cj][p]<<endl;;
    */
    next_gene[gene_i][p] = gene[cj][p];
  }
}

void Mutation(int ngene_i) {
  ++mutation_time;
  for (int i = 0; i < n_mutation_p; ++i) {
    int p = rand() % D + 1;
    next_gene[ngene_i][p] = rand() % ntype + 1;
  }
}

int Select() {
  double a = (double)rand() / RAND_MAX;
  int t = cumfreq.size() - 1;
  for (int i = 0; i < t; ++i) {
    if (cumfreq[i + 1].first > a)
      return cumfreq[i].second;
  }
  return cumfreq[t].second;
}

void Init(int nGreedy) {
  for (int i = 0; i < nGreedy; ++i) {
    greedyGene(i);
  }
  for (int i = nGreedy; i < population_size; ++i) {
    randGene(i);
  }
}

void makeCumFreq() {
  for (int i = 0; i < population_size; ++i) {
    double e = (double)evaluate(i);
    cumfreq.push_back(make_pair(e, i));
  }
  calcCumFreq();
}

void makeNextGeneration() {
  for (int d = 1; d <= D; ++d)
    next_gene[0][d] = elete[d];
  for (int i = 1; i < population_size; ++i) {
    int pi = Select();
    double crossrand = (double)rand() / RAND_MAX;
    if (crossrand < crossRate) {
      int pj = Select();
      while (pi == pj)
        pj = Select();
      CrossOver(i, pi, pj);
    } else {
      for (int j = 1; j <= D; ++j)
        next_gene[i][j] = gene[pi][j];
    }
    double murand = (double)rand() / RAND_MAX;
    if (murand < mutationRate) {
      Mutation(i);
    }
  }
  for (int i = 0; i < 50; ++i) {
    for (int j = 1; j <= D; ++j) {
      gene[i][j] = next_gene[i][j];
    }
  }
}

void GA(int n) {
  for (int i = 0; i < n; ++i) {
    makeCumFreq();
    makeNextGeneration();
    cumfreq.resize(0);
  }
}

void Output() {
  for (int d = 1; d <= D; ++d)
    cout << elete[d] << endl;
}

int main() {
  srand(seed);
  Input();
  Init(1);
  GA(3000);
  /*crossRate=after_crossRate;
  mutationRate=after_mutationRate;
  elete_select_prob=after_elete_select_prob;
  GA(1000);*/
  Output();
  // Info();
}