yukicoder No.390 最長の数列
解法
DPをします.
としておきます. 遷移は,
です. 右のを固定して配るDPにすると,
計算量はなります.
左を固定すると約数の列挙にかかるためとなり, ギリギリ間に合います.
感想
難しかったです.
No.462 6日知らずのコンピュータ
解法
まず, がであるときを考えます
このとき, 〜 桁のビットまで, ビットを立てる順番の場合の数がそのまま場合の数になります. 一度立てたビットは元に戻さないため, これらの数列たちはすべて異なるものになり, 答えはとなります.
のときを考えます.
目的の数列は, それぞれの要素を2進数で表したときのビットが立っている数でソートし, 立っているビットの数をみると , となり, ビットの数にかぶりはありません.
また, ビットの立て方から, この立っているビットの数でソートした数列(とします)の性質として, が成り立っている必要があります. (ここではビットごとの論理和)
言い方を変えると, ある要素より1つ大きな添字を持つものは, ビットを要素としてみたときに左の要素を部分集合として持っている必要があります. これらの性質を与えられたが満たしていないならば, 数列を作ることはできません. また, 立っているビット数が等しいものが存在しないことも必要ですが, (等しいとき, 両方の数を数列内に入れることはできない), これはすでに上の必要条件となっています, これらの制限をクリアできないものは0を出力します.
条件を満たした数列の場合の数は, 各の間のビットの埋め方の積となります. のハミング距離の階乗を順次かけていくと答えです.
感想
ビットシフトをする際, (1<< N) -1 と書くと, 1がint型として認識され, Nがint型を超えるような値となっていると望み通りの計算結果が得られないことがわかった. 次のように記述するとうまくいく.
(1LL << N) - 1
また, MODのとり忘れに気をつけたい.
yukicoder No.491 10^9+1と回文
解答
の性質に着目します. にたとえば123456をかけると, になります. ほかの数値に対しても, 数値が左側と右側にコピーされているような感じになります. これに着目すると, が回文となる場合は, 回文を掛け算した場合のみであることがわかります.
与えられたに対して (小数点切捨)
としたが, までのの倍数の数となります.
『以下の自然数であって回文であるようなものの数』が答えとなります.
回文の数を手元で概算すると, それほど多くないことに気づいたのですべてを列挙してソートし, 二分探索で数を数えることにしました.
回文の列挙は,
1桁, 2桁は自明
K桁目は, K-2,K-4,..(1 or 2)桁の回文を真ん中に置いて両サイドに1~9を置くことで生成することができます.
詳しいことは提出を見てください.
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ずらしていけば, すべての場合を取りつくせることになります. このずらしを行ったときに, 個の要望が満たされている数を調べ, 最大値をとると答えが出ます. しかし, 計算量はとなり, 制約から間に合いません.
入力のについて, あるマスが白だとしたら, は必ず黒になります. これを利用すると, 白の希望をすべて黒の希望に変換でき, を死にパラメータにすることができます.
また, 同じ性質よりについての周期があるため, それぞれ
としてよいことがわかります. よって, のマスのみを考えればよいこともわかります.
マスをずらしていったときに高速で希望と一致しているマスを数える方法を考えます.
そこで, 二次元の累積和を考えます.
二次元の累積和によってまでの正方形領域に含まれる希望の数を個計算します. これは, まず それぞれの希望について, としたあと,
とすることで計算できます.
あとはこの累積和をこねくりまわすと, 各ずらしについてで要望の数を求めることができます. (計算式がちょっとめんどうです).
また, 実は回ずらして計算する必要はなく, 縦横それぞれ回ずらしてかなわなかった要望の数も最大値として更新するようにすると, 回で済みます. 全体の白黒を反転すれば, 対応する市松模様があるからです.
感想
難しい.