/ 最近 .rdf 追記 編集 設定 本棚

脳log[20190929] AtCoder Beginner Contest 142/E問題 Get Everything



2019年09月29日 (日)

最終更新: 2020-05-06T23:25+0900

[AtCoder] AtCoder Beginner Contest 142E問題 Get Everything

アルゴリズムがどうとか、タイムがどうとかではない。答えが出たのが嬉しい! WA (Wrong Answer) はもう見飽きた!

 初めてのAC (AC / 1886 ms / 3960 KB)

全然実装方針が固まらなかった。何について繰り返し、どうなれば終了していいのか、さっぱりわからなかった。だから初めてまとまった数の AC が出た提出は総当たりだったし、AC でなければ当然 TLE だった。

そのうち N の上限が12と非常に小さいぞ、とか、コスト(a_i)の上限(10^5)は14ビットだぞ、とか気がついて、鍵を32ビット整数(※)にエンコードすることにした。※Ruby の埋め込み整数は32ビットないかもだけど>http://www.a-k-r.org/pub/2016-09-08-rubykaigi-unified-integer.pdf<実装依存ということでスクリプトからは隠されたらしい。

その鍵をどうすれば答えにつながるかという点 は、20110826p01.02の記憶がうっすら影響してる。今回は間違えずに、不安から慎重(無駄)な処理をすることは避けられたと思う。

あとは AC の数より多い WA を潰す長い長い迷路。もうお疲れなのであとは他人の提出を見てネタバレを楽しむのみ。

 Ruby による提出一覧

Ruby でも 500 ms を切ることができるらしい。200バイトちょっとのスクリプトで答えが出るらしい。ネタバレはもうちょっと先にしよう。

 2番目のAC (AC / 565 ms / 2684 KB)

タイムとメモリの代表値には最悪の数字が選ばれる。条件式をひとつ付け加えたら、最悪だった 1886 ms が 223 ms に縮まった。これはしてやったり。

鍵の包含関係は気になっていたんだけど(※このときの経験から。「他ののサブセットになってるのがあったら除外できる」)、チェックして除外する適所がわかっていなかった。WA を潰すのでそれどころではなかったし、そのために処理と負荷が増えては本末転倒だし。

あとはこの、完全に手続き指向で長ったらしい解答を根本から覆す天啓が降っては来ないものか。

 他人の提出を見た。

使われている変数名 dp がすべてを語っているのではないだろうか。このパターンは何度も経験している。「それ DP で」案件だったのだろう。でも DP(動的計画法)の一語で理解できたことがないまま今に至ってるんだよなあ。持つデータに対して頭の整理が追いつかないもので。

平均タイムで見ると自分の解法も悪くないと思う。Ruby の提出で一番速いタイムが 481 ms だから、最悪タイム(565 ms)を記録した最後の入力に対策できれば一矢報いられるのでは?

 チューニングした (AC / 476 ms / 3836 KB)

狙い通りに最悪タイムだった 565 ms が 476 ms に改善した。スクリプトって書けば書くほど遅くなるのが普通だから珍しい。

しかし、多くの入力で実行時間とメモリ使用量が微減している中、02-random-17 という入力だけ特異的に 1788 KB が 3836 KB に増大している。これってつまり何が起こっているんだろう。大量の使い捨てオブジェクト? どこから? Array#shift(n)?

 さらにチューニングした (AC / 25 ms / 2424 KB)

桁が違っていて効果に自分でびびっている。「インタープリタ型言語でトップクラスの速さ」。やったぜ。でもやっぱり、ソースが長たらしくて汚い。

(組み合わせではなくコストによる)順序をつけて、不要な処理をスキップし(※nextステートメントの数を見よ。あ、<= にできるところが1か所 < になってる。無駄だ)、ソートにコストをかけないように2本目3本目のキューを細かに操作し(※あ、bsearch_indexの条件が潜在的にバグってる。+ を | にして <= を < にしないと)、答えが見つかり次第打ち切るからこその速さであって、(1本のキューと)手続きが中心になるのは避けられないとは思うが……。

ちなみに、Corvvs という人の提出(https://atcoder.jp/contests/abc142/submissions/7795963)を参考にした(「あ、全適用は S の要素だけでいいんだ」)。この人の ID はもう覚えてしまっていて、この前「あとで知ったのだけど、Ruby には Integer#bit_length という便利メソッドが予め用意されていた」と書いたのだけど、その「あとで」がこの提出だった>https://atcoder.jp/contests/abc141/submissions/7557027。ひと味違った解答を書く人だと思う、それを Ruby で。

そうそう、最初の遭遇はこれだった「Rubyで一番速いのはこれ」。それが「「Rubyで一番速いの」を真似して勉強」へと繋がり、現在の AtCoder との付き合い方が決まった。「自ら取り組み考えた「問題・課題」に対する異なる方向からのアプローチは、よく身に付く貴重な学びの機会」の実践。優れたお手本に事欠かないし、自分の方でもそれを理解する準備が整っている。