AtCoder Regular Contest 104

まえがき

ARCなんてめちゃめちゃ久しぶりですね...。前回のARCから2年も経ってるらしいですよ。

というか、2年前とperfが変わってなくてショック受けました。

f:id:EugleNa:20201003232543p:plain

コンテストリンク

atcoder.jp

A問題

一瞬迷いますが、落ち着いて(A+B)/2と(A-B)/2を出力すればおkです。

軽く腕ならしするつもりで[AC]していきましょう。

提出コード

B問題 

解法

Tに含まれる'A'と'T'、'C'と'G'の個数が同じの時に条件を満たします。

N≦5000なので、愚直にシミュレーションしても間に合います。

提出コード

感想

制約がN≦200000でも、Zero-Sum Rangesみたいにすれば簡単に解けます。N≦5000なのはwriterさんの優しさでしょうか。

C問題

これすき

解法

ある人がk階上がるとき、その間に乗り降りする人も全員k階上がるので、結局「ある階からk-1階上の階までの人がみんなk階上がる」ってことになります。

f:id:EugleNa:20201004012829p:plain

すると、その集団で最初の人が乗る前と最後の人が降りる後にはエレベーターはすっからかんになります。

そうすると、

 dp[i]=エレベーターがi階目を出発する時にすっからかんになりうるかどうか

というbool値を持つDPが書けて、状態O(N)遷移O(N)遷移時間O(N)でO(N^3)時間になって無事ACです。

提出コード

感想

コンテスト中の自分は、「ある人Aがk階上がるとき、その間に乗る人もみんなk階上がるから、Aさんが乗る階からk-1階上の階までの人はみんなk階上がるよね」と、Aさんが乗ってる間に人が降りる可能性を無視して脳内考察してました。

どっちみち同じ結論になるのでまぁ結果オーライなんですが、危ない危ない...。

D問題

こっからACできなかった問題です。

解法

まず真っ先に常套テク、全体をxズラして平均を0にします。

ズラした後の数を正と負に分けると、それぞれのグループで選んだ数の和が同じになればいいので、

 dp[i][S] = 1, 2, ... iのそれぞれをK個以下選んでSにする方法の個数

が求まればSをO(N^2K)通り全探索で解けます。

このDPは累積和を使って遷移してあげると状態O(N^3K)遷移O(1)でO(N^3K)時間で解けます。

感想

コンテスト中は、常套テク以降の方針を決めあぐねて5乗高速化とか6乗高速化とかしてました(もちろん軒並み失敗)。

正と負にグループ分けもちょっと考えましたが、それ以降が思いつかなくてEに移ってました。

E問題

解法

X_iを座圧すると全要素がN以下になるので、座圧後の数列は高々6^6=46656通りです。

X_iのLISを考える代わりに座圧後の列のLISを考えてもLISの長さは変わらないので、

 Σ(X_iのLISの長さ) = Σ(座圧後のLISの長さ)×(座圧してその列になるX_iの個数)

と変形できます。

座圧後の数列を一つ固定すると、そのLISの長さは全探索で求まり、(座圧してその列になるX_iの個数)はDPで求まる...らしいです。[要出典]

感想

コンテスト中はDPではなく多項式をこねて考えてましたが、時間内に実装しきれませんでした。

僕が思いついた多項式解法は実質DP解法の下位互換みたいなものなので、完全に考察不足って感じでしたね...。

 

あとがき

C(600)は相性良くてすんなり解けたのに、D(700)とE(700)でだだ詰まりしてボコボコになりました。

Dを解き続けるのがいいムーブだったのかな......わからん

蛇足

コンテスト中はMegalovaniaの100分耐久をBGMにしてました。

100分耐久はいいぞ〜

www.youtube.com