Align
Tenka1 Programmer Beginner Contest-C "Align"
めちゃくちゃコード読みにくいので見ないでくださいw
恥ずかしいです
提出コード
考察
作る数列をとします.
このとき,あるについてや,となるようなものは存在しないことが次のようにわかります.
共に同様に示せるため,前半のみ示します.
この項間で差を見てみると,
となり,は間に挟まっている意味がない,つまり別の位置にを移動させた方がより全体の和を最大化できます.
も同様にあり得ません.
以上より,場合分けは次のような通りを試す必要があります.
・
・
が偶数か奇数かによって末尾の状況は違います.
具体例として,を考えます.
と,のパターンで隣接差の和を計算して大きい方が答えです.
・のとき
答えは
です.
明らかに,indexが奇数のときは倍して足す,indexが偶数のときは倍して引く,という操作を繰り返せばOK.
ただし先頭は倍して引いて,末尾も倍して引きます.(要はそのまま足し引き)
これより,各は倍して足す,倍して足す,倍して引く,倍して引く,のいずれかに分類されます.
(なお,倍して足し引きするのは先頭か末尾だけなので実際は倍して足し引きがメインです)
最大化したいので, ]の大きい数字ほど倍したいです.
ということで, ]の大きい方から倍して足す,倍して足す,倍して引く,倍して引く,と順に和を求めていくことでで答えが得られます.
が偶数のときは末尾をそのまま足しますが,違いはそれだけです.
・のとき
上の場合分けと同様にできます.
が偶数か奇数かで先頭と末尾が少しずつ違います.
感想
最初はlistを作って小さい数大きい数小さい数...と新しい数列を作っていましたが無事に沼にハマりました.
今回はしっかり解説を見てしまいました.
何ヶ月後かにはスムーズに解きたい.