文学徒が競プロをするブログ

競技プログラミングの精進を記録していきます

AtCoder Beginner Contest 189 反省

めちゃくちゃ不甲斐ない。Dが通せなかったのは本当にひどかった。早い段階で方針分かってたのに通せないの最悪すぎて言葉も出ません。

A問題 Slot

if文を書きます

B問題 Alcoholic

 \sum_{i=1}^{k} V_i \times P_i \times \frac {1}{100} > X となる最初の添え字を求める問題。こういうのが誤差で死亡しがちなのは経験上(去年のパナソニックコンなど)知っていて、適当に式変形をするといい。

 \sum_{i=1}^{k} V_i \times P_i > X \times 100 となる最初の添え字を求めればいい。

C問題 Mandarin Orange

 N \leq {10}^{5}とかならDに置かれていても違和感ない問題。普通に初手困った。
良い解法がぱっと思い浮かばなかったから、セグ木貼って O({N}^{2} \log N)ワンチャンお祈りしたけどダメだった。

よく見るとTLが1.5secだったし流石に反省して速い解法考えたけど O({N}^{2})許すなら許してほしいね。

結局Minimum Sumみたいに小さい順にソートしてsetでindexを管理するやり方で解いた。聞くところによると最大長方形なるアルゴリズムで解けるんですね。初めて知りました。

D問題 Logical Expression

今回の反省の本題。まあANDとORでどう考えても数えるやり方が変わってくるからDPするしかないんですね。
敗因は何故か80分もあってこの簡単そうな遷移を詰め切れなかったこと。85分後に通せました。

え、文字にすると意味の分からなさがすごいな。このDP、バグやらで時間かけるとしても10分くらいの見た目じゃないですか?

このDPの遷移を時間通りに詰め切れないのは明らかにおかしいので、原因と対策を考えていく。

今回の件は、「サンプル等からフィーリングで何となくDPの状態の持ち方や遷移を考えていく」という論理的思考弱者ならではの思考パターンが招いた失敗だった。
この問題はたまたまサンプルが少なく、またサイズが小さかったために考慮漏れが頻発してしまった。また手で大きめのサンプルを作ろうとして時間を食ってしまった。それらがこの失敗を生んだと結論するのが妥当である。

実験が大切な問題とか、サンプル見ないと意味が分からない類の問題では確かにサンプルからエスパーしていくこともあるけど、それ以外の問題でやるべきことではない。

DPに限らず、今日を境として脱却することを誓います。

さて、改めてどうすべきかと考えると、やはり数式ベースで場合分けを考えていくという方針が良いように思う。
自分は何となくで問題が解けるほど地頭が良くないので、出来るだけ扱いやすい統一的な構造で問題を捉えていく癖をつけていかないと本当に水色に戻れなくなる。

数学的な考え方だとmaspyさんのDPに関する考え方がシンプルでかっこいいので、参考にしたいなあ。

ひとまずありがちな状態の持ち方として f(i) y_iがTrueとなるものの個数とおく。そして場合分けを考える。

明らかな場合分けとして S_iがANDかORかを考えると

  • ANDの場合

ANDの時は y_{i-1}の値がTrueでかつ x_iもTrueの場合しか y_iでTrueになることはないので

 f(i) = f(i-1)

となる

  • ORの場合

ORの時は更に場合分けをする必要がある。 x_iをTrueとした場合とFalseとした場合である。
ちなみに本番ではここで y_{i-1}がTrueの場合とFalseの場合を考えてしまい、混乱して時間をロスした(その場合分けだと y_iがTrueとなる数とFalseとなる数両方を持つ必要がある)。そもそも定義からしてそんな場合分け考えるなよ。

 x_i = Trueのとき

 y_{i-1} = True

でも

 y_{i-1} = False

でもTrueになるので、そこまでの全ての場合の数を足しこむ。

 f(i) += {2}^(i)

 x_i = Falseのとき

 y_{i-1} = Trueの数だけTrueに出来るので

 f(i) += f(i-1)

これでおしまい。うーん。サンプルじゃなくて数式をいじる力をつけたい。

E問題

コンテスト後に問題をしっかり読んだ。
色々考えたけど、全ての点が統一的に動く設定で、多分操作が単純な計算式に圧縮されるようなタイプの問題だと思った。

操作を数式でうまいこと記述できれば上から舐めていって、出力に当たったらその数式をもとの座標に適用すればいいんじゃないですかね。

あとはそのうまいことやる数式を見つければ良くて、何か回転とか平行移動とかでググる行列式が出てきた。行列とか習ってません。おしまいです。

うーんこまっちゃうね。

これに全てが書かれているような気がするんですが、読めない。でもなんかそれっぽい。
これがEで出るってことは行列ライブラリは持っておけってことなのか。ちょっと行列勉強してきます。

解説見た。うーん、考え方はあってたなと思ったけどナイーブ解法見て爆笑した。なにこれ天才?それはそうすぎてびっくりした。ギャグっていうには実装が重そうだけど実質ギャグだろ。