#ifndef __COMMON_HPP__ #define __COMMON_HPP__ #include #include #include #include using namespace std; using ll = long long; using mint = atcoder::static_modint<100000000>; namespace common { int n; vector> a; void read(); void update(vector>&); inline int diff(const mint, const mint); inline ll calc_score(const vector>&); }; void common::read() { cin >> n; a.resize(n, vector(n)); for(int i = 0; i < n; i++) { for(int j = 0; j <= i; j++) { int tmp; cin >> tmp; a[i][j] = tmp; } } } void common::update(vector> &b) { for(int i = n-1; i > 0; i--) { for(int j = 0; j < i; j++) { b[i-1][j] = b[i][j] + b[i][j+1]; } } } inline int common::diff(const mint x, const mint y) { int d = (x-y).val(); return min(d, 100000000-d); } inline ll common::calc_score(const vector> &b) { ll score = 0; for(int i = 0; i < n; i++) { for(int j = 0; j <= i; j++) { score = max(score, diff(a[i][j], b[i][j])); } } return 50000000-score; } #endif #ifndef __STATE_HPP__ #define __STATE_HPP__ #ifndef __RYUKA_HPP__ #define __RYUKA_HPP__ #include using namespace std; struct RandGenerator { random_device seed_gen; mt19937 engine; mt19937_64 engine64; static const int pshift = 1000000000; RandGenerator() : engine(seed_gen()), engine64(seed_gen()) {} int rand(int mod) { return engine() % mod; } long long randll(long long mod) { return engine64() % mod; } bool pjudge(double p) { int p_int; if(p > 1) p_int = pshift; else p_int = p * pshift; return rand(pshift) < p_int; } } ryuka; #endif #include #include #include using namespace std; using namespace common; extern RandGenerator ryuka; struct State { static constexpr long long inf = 1LL<<60; long long score; vector> b; State() : score(-inf) {}; long long calc_score(); void print(); static State initState(); static State generateState(const State& input_state); }; long long State::calc_score() { score = common::calc_score(b); return score; } void State::print() { for(int i = 0; i < n; i++) { cout << b[n-1][i].val() << (i == n-1 ? '\n' : ' '); } } State State::initState() { State res; res.b = a; update(res.b); res.calc_score(); return res; } State State::generateState(const State& input_state) { State res = input_state; int i = ryuka.rand(n); int v = ryuka.rand(100000000); res.b[n-1][i] = v; update(res.b); res.calc_score(); return res; } #endif #ifndef __ANNEALER_HPP__ #define __ANNEALER_HPP__ #ifndef __TOKI_HPP__ #define __TOKI_HPP__ #include #include struct Timer { double global_start; double gettime() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + tv.tv_usec * 1e-6; } void init() { global_start = gettime(); } double elapsed() { return gettime() - global_start; } } toki; #endif extern Timer toki; extern RandGenerator ryuka; template struct IterationControl { long long iteration_counter; long long swap_counter; double average_time; double start_time; IterationControl() : iteration_counter(0), swap_counter(0) {} STATE climb(double time_limit, STATE initial_state); STATE anneal(double time_limit, double temp_start, double temp_end, STATE initial_state); }; template STATE IterationControl::climb(double time_limit, STATE initial_state) { start_time = toki.gettime(); average_time = 0; STATE best_state = initial_state; double time_stamp = start_time; cerr << "Starts climbing...\n"; while(time_stamp - start_time + average_time < time_limit) { STATE current_state = STATE::generateState(best_state); if(current_state.score > best_state.score) { swap(best_state, current_state); swap_counter++; } iteration_counter++; time_stamp = toki.gettime(); average_time = (time_stamp - start_time) / iteration_counter; } cerr << "Iterated " << iteration_counter << " times and swapped " << swap_counter << " times.\n"; return best_state; } template STATE IterationControl::anneal(double time_limit, double temp_start, double temp_end, STATE initial_state) { start_time = toki.gettime(); average_time = 0; STATE best_state = initial_state; double elapsed_time = 0; cerr << "Starts annealing...\n"; while(elapsed_time + average_time < time_limit) { double normalized_time = elapsed_time / time_limit; double temp_current = pow(temp_start, 1.0 - normalized_time) * pow(temp_end, normalized_time); STATE current_state = STATE::generateState(best_state); long long delta = current_state.score - best_state.score; if(delta > 0 || ryuka.pjudge(exp(1.0 * delta / temp_current)) ) { swap(best_state, current_state); swap_counter++; } iteration_counter++; elapsed_time = toki.gettime() - start_time; average_time = elapsed_time / iteration_counter; } cerr << "Iterated " << iteration_counter << " times and swapped " << swap_counter << " times.\n"; return best_state; } #endif #include using namespace std; using namespace common; int main() { read(); IterationControl sera; State stat = sera.climb(1.8, State::initState()); stat.print(); cerr << "my score = " << stat.score << endl; }