Loading...
1/10/2025
ABC204E - Rush Hour2の解法を一部含みます(というかこれを前提に書いてます)。 三分探索がうまくいかなかったときの気持ちを述べているだけなので、あまり参考にはならないかもしれません。ご了承を。
辺には重みの他にというパラメータが存在します。時刻においてその辺を利用する場合はの重みが追加で加算されます。各頂点で好きなだけ時間を潰せるとき、頂点から頂点の最短距離を知りたいです。 ある頂点に時刻に到達したときに、未達の隣接する頂点に移動するための最短の時刻がわかれば自明にDijkstra法です。よって、以下の問題を考えます。
とする。を最小とするような非負整数を求めよ。
直感的に凸な気がします。のときはがおおきくなり、反対にが大きくなるとそれはそれではおおきくなるので。 凸のときはどうすればいいですか?そうですね三分探索です。適当に実装をします。
...(前略) let mut l = t; let mut r = INF/10; while r - l > 2 { let m1 = l + (r - l) / 3; let m2 = r - (r - l) / 3; if d / (t + 1 + m1) + m1 > d / (t + 1 + m2) + m2 { l = m1; } else { r = m2; } } ...
サンプルが合いました。提出をします。提出
...WAです1。そんなぁ。とりあえず検索をかけると、記事を見つけます2。
以下の凸or凹関数は全て狭義であることに注意してください!
あ~~~~~~~~~~~~~。もしかして、広義の凸3ではバグりますか?
あまりグダグダと書いていても仕方がないので結論を述べることにします。 問題4の正体はそもそも三分探索のアルゴリズムが最小値を求めるアルゴリズムではなく、関数の極値を求めるアルゴリズムである、という点です。
関数が常に狭義単調増加・狭義単調減少のいずれかを取り、かつその範囲で極小を取る点がただ一つであるならばその範囲において極小を取る点が最小を取る点に一致するというだけで、最小値を求めるアルゴリズムではないわけです。
もし広義単調増加(減少)となるような区間が存在すると、それが極値として引っかかるんだなぁというそういう話でした。おしまい。
TLEも出ているがこれは本当にわかりません Dijkstraの計算量に一つlogが付く程度だと思うんですが、まぁループの終了条件を適当に書いたのが良くなかったのかもしれません。 ↩
出典: 二分探索と三分探索の数学的な解説とバグらせない実装方法(qiita) - @DaikiSuyama(Daiki Suyama) ↩
こんな用語は存在しなさそう 適当書いてごめん ↩
issue ↩