結果

問題 No.2573 moving up
ユーザー takumi152takumi152
提出日時 2023-12-02 17:05:00
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 1,903 ms / 2,000 ms
コード長 7,179 bytes
コンパイル時間 3,510 ms
コンパイル使用メモリ 261,904 KB
実行使用メモリ 6,676 KB
最終ジャッジ日時 2023-12-06 15:49:46
合計ジャッジ時間 65,581 ms
ジャッジサーバーID
(参考情報)
judge15 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1,903 ms
6,676 KB
testcase_01 AC 1,902 ms
6,676 KB
testcase_02 AC 1,901 ms
6,676 KB
testcase_03 AC 1,902 ms
6,676 KB
testcase_04 AC 1,902 ms
6,676 KB
testcase_05 AC 1,903 ms
6,676 KB
testcase_06 AC 1,902 ms
6,676 KB
testcase_07 AC 1,902 ms
6,676 KB
testcase_08 AC 1,901 ms
6,676 KB
testcase_09 AC 1,902 ms
6,676 KB
testcase_10 AC 1,902 ms
6,676 KB
testcase_11 AC 1,902 ms
6,676 KB
testcase_12 AC 1,903 ms
6,676 KB
testcase_13 AC 1,901 ms
6,676 KB
testcase_14 AC 1,902 ms
6,676 KB
testcase_15 AC 1,902 ms
6,676 KB
testcase_16 AC 1,902 ms
6,676 KB
testcase_17 AC 1,902 ms
6,676 KB
testcase_18 AC 1,903 ms
6,676 KB
testcase_19 AC 1,902 ms
6,676 KB
testcase_20 AC 1,901 ms
6,676 KB
testcase_21 AC 1,902 ms
6,676 KB
testcase_22 AC 1,902 ms
6,676 KB
testcase_23 AC 1,901 ms
6,676 KB
testcase_24 AC 1,903 ms
6,676 KB
testcase_25 AC 1,902 ms
6,676 KB
testcase_26 AC 1,902 ms
6,676 KB
testcase_27 AC 1,902 ms
6,676 KB
testcase_28 AC 1,901 ms
6,676 KB
testcase_29 AC 1,902 ms
6,676 KB
testcase_30 AC 1,903 ms
6,676 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

  #ifdef __GNUC__
  #pragma GCC optimize ("O3")
  #pragma GCC optimize ("unroll-loops")
  #pragma GCC target ("avx2")
  #endif

  #include <iostream>
  #include <fstream>
  #include <iomanip>
  #include <vector>
  #include <array>
  #include <algorithm>
  #include <utility>
  #include <string>
  #include <queue>
  #include <stack>
  #include <set>
  #include <unordered_set>
  #include <unordered_map>
  #include <bitset>
  #include <random>
  #include <functional>
  #include <cmath>
  #include <cassert>

  #ifdef _MSC_VER
  #include <intrin.h>
  #else
  #include <x86intrin.h>
  #endif

  struct xorshift64 {
    unsigned long long int x = 88172645463325252ULL;
    inline unsigned short nextUShort() {
      x = x ^ (x << 7);
      return x = x ^ (x >> 9);
    }
    inline unsigned int nextUShortMod(unsigned long long int mod) {
      x = x ^ (x << 7);
      x = x ^ (x >> 9);
      return ((x & 0x0000ffffffffffff) * mod) >> 48;
    }
    inline unsigned int nextUInt() {
      x = x ^ (x << 7);
      return x = x ^ (x >> 9);
    }
    inline unsigned int nextUIntMod(unsigned long long int mod) {
      x = x ^ (x << 7);
      x = x ^ (x >> 9);
      return ((x & 0x00000000ffffffff) * mod) >> 32;
    }
    inline unsigned long long int nextULL() {
      x = x ^ (x << 7);
      return x = x ^ (x >> 9);
    }
    inline double nextDouble() {
      x = x ^ (x << 7);
      x = x ^ (x >> 9);
      return (double)x * 5.42101086242752217e-20;
    }
  };

  struct timer {
    double t = 0.0;
    double lastStop = 0.0;
    bool stopped = false;
    timer() {
      restart();
    }
    inline void restart() {
      t = now();
      stopped = false;
    }
    inline void start() {
      if (stopped) {
        t += now() - lastStop;
        stopped = false;
      }
    }
    inline void stop() {
      if (!stopped) {
        lastStop = now();
        stopped = true;
      }
    }
    inline double time() {
      if (stopped) return lastStop - t;
      else return now() - t;
    }
    inline double now() {
      #ifdef _MSC_VER
        #ifdef LOCAL
          return __rdtsc() * 2.857142857142857e-10; // 1 / 3.5e9, for local (Ryzen 9 3950X)
        #else
          //return __rdtsc() * 3.5714285714285715e-10; // 1 / 2.8e9, for AWS EC2 C3 (Xeon E5-2680 v2)
          //return __rdtsc() * 3.4482758620689656e-10; // 1 / 2.9e9, for AWS EC2 C4 (Xeon E5-2666 v3)
          //return __rdtsc() * 3.333333333333333e-10; // 1 / 3.0e9, for AWS EC2 C5 (Xeon Platinum 8124M / Xeon Platinum 8275CL)
          return __rdtsc() * 4.3478260869565215e-10; // 1 / 2.3e9, for yukicoder judge
        #endif
      #else
        unsigned long long l, h;
          __asm__ ("rdtsc" : "=a"(l), "=d"(h));
        #ifdef LOCAL
          return (double)(l | h << 32) * 2.857142857142857e-10; // 1 / 3.5e9, for local (Ryzen 9 3950X)
        #else
          //return (double)(l | h << 32) * 3.5714285714285715e-10; // 1 / 2.8e9, for AWS EC2 C3 (Xeon E5-2680 v2)
          //return (double)(l | h << 32) * 3.4482758620689656e-10; // 1 / 2.9e9, for AWS EC2 C4 (Xeon E5-2666 v3)
          //return (double)(l | h << 32) * 3.333333333333333e-10; // 1 / 3.0e9, for AWS EC2 C5 (Xeon Platinum 8124M / Xeon Platinum 8275CL)
          return (double)(l | h << 32) * 4.3478260869565215e-10; // 1 / 2.3e9, for yukicoder judge
        #endif
      #endif
    }
  };

  using namespace std;

  typedef long long int ll;
  typedef unsigned long long int ull;
  typedef pair<int, int> Pii;
  typedef unsigned char uchar;

  const ll mod = 1000000007;

  timer theTimer;
  xorshift64 theRandom;
  mt19937 theMersenne(1);

  // hyper parameters

  // structs

  // enums

  // constants

  // inputs
  int height, width;
  vector<Pii> initial_position;

  // outputs
  int ans;

  // environment
  vector<vector<int>> unit_cost_of_position;

  // state
  vector<int> position_to_move;

  // score
  vector<int> unit_cost;
  int total_cost;

  void get_first_input() {
    cin >> height >> width;
    initial_position = vector<Pii>(width);
    for (auto &[x, y]: initial_position) {
      cin >> x >> y;
      x--;
      y--;
    }
  }

  void init() {
    unit_cost_of_position = vector<vector<int>>(width, vector<int>(width));
    for (int i = 0; i < width; i++) {
      for (int j = 0; j < width; j++) {
        if (initial_position[i].second - initial_position[i].first <= j && j <= initial_position[i].second) unit_cost_of_position[i][j] = initial_position[i].first;
        else unit_cost_of_position[i][j] = initial_position[i].first + min(abs((initial_position[i].second - initial_position[i].first) - j), abs(j - initial_position[i].second));
      }
    }

    position_to_move = vector<int>(width);
    for (int i = 0; i < width; i++) position_to_move[i] = i;

    unit_cost = vector<int>(width);
  }

  void update_score_full() {
    for (int i = 0; i < width; i++) {
      unit_cost[i] = unit_cost_of_position[i][position_to_move[i]];
    }
    total_cost = 0;
    for (int i = 0; i < width; i++) {
      total_cost += unit_cost[i];
    }
  }

  int get_score() {
    return total_cost;
  }

  void solve() {
    update_score_full();

    int score = get_score();
    int last_score = score;
    int best_score = score;

    const double base_temperature = 1e2;
    const double target_temperature = 1e-2;
    // const double decay_rate = 4e-5;
    double temperature = base_temperature;

    int iter_count = 0;
    double time_start = theTimer.time();
    const double time_limit = 1.900;

    while (theTimer.time() < time_limit) {
      double roll = theRandom.nextDouble();
      if (roll < 1.00) {
        int i1 = theRandom.nextUIntMod(width);
        int i2 = theRandom.nextUIntMod(width);
        if (i1 == i2) continue;

        swap(position_to_move[i1], position_to_move[i2]);

        update_score_full();

        score = get_score();

        #ifdef DEBUG
        if (iter_count % 100000 == 0) cerr << iter_count << " " << score << " " << last_score << " " << best_score << " " << temperature << " " << theTimer.time() << endl;
        #endif

        if (score <= last_score) {
          last_score = score;
          if (score < best_score) {
            best_score = score;
          }
        }
        else if (theRandom.nextDouble() < exp(double(last_score - score) / temperature)) { // accept
          last_score = score;
        }
        else { // rollback
          swap(position_to_move[i1], position_to_move[i2]);
          score = last_score;
        }
      }

      // temperature *= 1.0 - decay_rate;
      temperature = exp(log(base_temperature) - ((log(base_temperature) - log(target_temperature)) * ((theTimer.time() - time_start) * (1.0 / (time_limit - time_start)))));
      iter_count++;
    }

    cerr << "iter_count   = " << iter_count << endl;
    cerr << "score        = " << score << endl;
    cerr << "best_score   = " << best_score << endl;
    cerr << "temperature  = " << temperature << endl;

    ans = best_score;
  }

  void output_ans() {
    cout << ans << endl;
  }

  int main(int argc, char *argv[]) {
    cin.tie(0);
    ios::sync_with_stdio(false);

    get_first_input();

    init();
    solve();

    output_ans();

    return 0;
  }
0