yukicoder No.496 ワープクリスタル (給料日前編)
解法
dpします. どんなdpかというと,
です. まずこのdpテーブルにまで徒歩でいったときのコストを入れておきます.
このdpテーブルに対し, ワープクリスタルを1つずつ使っていき, コストが小さくなる部分を小さくしていきます.
具体的には
をすべてのワープクリスタルに対して検査すればが答えです.
しかし, 同じワープクリスタルは二度使えないため, ゴールから更新していくか, 別の配列に結果を一時保存しておいてあとでまとめて更新するかのどちらかが必要です. (これをせずに順次スタート地点から更新すると, 更新された地点を経由する路で再びワープクリスタルを用いる可能性がある.)
感想
ナップザック風です.
yukicoder No.314 ケンケンパ
解法
ケンケンパの生成について, 3つの状態があります.
- パで終わっている
- 末尾にケンが1回連続で出現して終わっている
- 末尾にケンが2回連続で出現して終わっている
遷移しうる状態は
1 → 2
2 → 1 , 3
3 → 1
よりDPを組み立てると, (0-indexedで組みます)
として, 右辺を固定して配るdpをすると,
初期値
これをについて回すと,
が答えです.
感想
前後のみを見るdpなので, 領域を節約できないかとi%2 でインデックスしたもので実装してもみたものの, なんでかバグって正しい答えが出力されませんでした... どうしてでしょう.
ABC 076 D - AtCoder Express
解法
まず, サンプルをみると速度・時刻が0.5刻みで決まっていきそうなことがわかるので, 時刻・速度ともに2倍に引き伸ばします. これで多少は考えやすくなります.
前方向から順に速度を決めていくと, 減速しきれない区間が現れたりしてうまくいかないので, 到着する場所から, とりうる最大の速度をdpします.
(各区間ごとの最高速度)と(一秒後の最高速度+1)の小さい方が, とりうる最大の速度となるのでこれをすべての時刻について回します.
あとは, スタート地点からゴール地点までにおいて, 取りうる最大の速度について, 貪欲に加速しながら台形の面積を加算していくと答えが求まります.
時刻と速度を2倍に引き延ばしているので, 面積を4で割る必要があります.
感想
先に各時点での最大速度を求めるのは発想としては自然だと思います(思いつきませんが). しかし, 各時点での最大速度を求めるときに区間の境目においてはちょっと処理がややこしく, そこだけ分けて考えるとよいです. (はに含まれているため, 双方の速度制限を満たしている必要があります. )
ABC 086 Checker
問題
解法
まず愚直な解法について考察します.
この問題の1辺が大きさの市松模様について, まずどこかの黒い正方形の左下に座標を置きます.
市松模様は無限に続いているので, この黒い正方形について右に1から2K-1, 上に1から2K-1ずらしていけば, すべての場合を取りつくせることになります. このずらしを行ったときに, 個の要望が満たされている数を調べ, 最大値をとると答えが出ます. しかし, 計算量はとなり, 制約から間に合いません.
入力のについて, あるマスが白だとしたら, は必ず黒になります. これを利用すると, 白の希望をすべて黒の希望に変換でき, を死にパラメータにすることができます.
また, 同じ性質よりについての周期があるため, それぞれ
としてよいことがわかります. よって, のマスのみを考えればよいこともわかります.
マスをずらしていったときに高速で希望と一致しているマスを数える方法を考えます.
そこで, 二次元の累積和を考えます.
二次元の累積和によってまでの正方形領域に含まれる希望の数を個計算します. これは, まず それぞれの希望について, としたあと,
とすることで計算できます.
あとはこの累積和をこねくりまわすと, 各ずらしについてで要望の数を求めることができます. (計算式がちょっとめんどうです).
また, 実は回ずらして計算する必要はなく, 縦横それぞれ回ずらしてかなわなかった要望の数も最大値として更新するようにすると, 回で済みます. 全体の白黒を反転すれば, 対応する市松模様があるからです.
感想
難しい.
yukicoder No.607 開通777年記念
解法
駅に到着するごとに条件を満たしているかを調べる必要があります.
駅に到着してからの人員の増減を配列に入れて管理し, その都度累積和を取り直します.
までの累積和のなかで2つ選ぶと, その差分を見ればその区間内の人数の和がわかります. ここで選ぶ区間の片側(右側)を固定し, 『もう一方の端をうまく選んで区間内の乗客を777人にできるか?』という問題を考えます. 累積和は単調増加であるため, いま注目している添字に対し, を二分探索で高速に調べることができます.
これが見つかったとき, "YES"を出力し, 見つからなかったときは最後に"NO"を出力します.
これをクエリの数回だけやるので, 全体の計算量の見積もりはとなり, この制約では間に合います.
ABC 106 反省
A問題
解法
道を端っこに移動させるとの面積になります.
B問題
解法
制約が小さいのでまでの奇数について約数をすべて調べ, 8個のものをカウントします.
C問題
解法
回数が十分大きいので, 番目まで1が続くかどうかを調べ, 1でないものが出現したらその数を出力し, 1が続いていたときは1を出力します.
D問題
解法
まず愚直な解法を考えます. ある配列をすべて0に初期化して用意しておき, すべての について とし, それぞれの数をカウントしておきます.
あるクエリに対しては,
なるに対し,
が答えとなります.
この解法の計算量はとなり, TLEします.
この解法において,
を計算する部分は, あらかじめ配列の累積和をとっておくことでループを1つ減らすことができます.
具体的には, 下の式が成り立ちます.
これでとなるので, 間に合います.
感想
コンテスト中はいろいろ解法がごっちゃになり, ややこしいコードを書いていたらコンテストが終わっていました.
あきらかなTLEコードでも書いて実験して改良点を探す, ということができてないように思えた. 愚直解がだめとわかっていてもとりあえず作ってみてそこから考えてみる, というのが重要だと感じた.
あと個人的に累積やしゃくとりなどを用いて計算量を減らす問題が苦手だと感じた. 演習を増やしたい.
yukicoder No.523 LED
解法
LEDをポチポチする順番を順列にして考えてみると, 例えばN=3のとき, ①①②②③③の並べ方を数える問題になります. このとき, 同じ番号のものは区別せず, 場合の数はとなります. 一般のNに対して答えは次の式で表されることがわかります.
制約からはループを回しながら剰余をとっても間に合います. は, まず繰り返し二乗法を用いてとなるを求めた後, さらに繰り返し二乗法を用いてフェルマーの小定理
からの逆元を求め, を計算して答えです.
その他
実は答えの式は
より
と変形できるため, 一回のfor文で求めることもできます. スゴイ