ARC138 A の公式解説がよく理解できなかった人向けの解説記事です。
執筆時レート:茶
問題文→https://atcoder.jp/contests/arc138/tasks/arc138_a
公式解説→https://atcoder.jp/contests/arc138/editorial/3746
目次
問題
長さ の整数列 が与えられる。
の先頭 項の和をスコアとし、入力で与えられた のスコアを とする。
において任意の回数だけ隣接する 要素をswapすることにより、スコアを 以上にすることは可能か。
可能ならば最小の操作回数を出力し、可能でないならば を出力せよ。
制約
- 入力される値はすべて整数
確認
要素を入れ替えることをswapと言います。
隣接する 要素をswapする操作を適当に行うことで、他の要素の順番はそのままに、ある要素を移動させることができます。
解説
具体的なケースで考えてみます。
この場合、最適解の一つとして、次のような移動が考えられます。
赤丸の要素は、移動前後で青エリア内⇄外の移動をした要素です。
スコアは から に増加しており、確かに目的は達成できています。
次に、この解の操作回数について考えてみます。
赤丸の要素は青エリア内⇄外の移動をしなければなりません。
青エリア内→外で移動させる各要素をそれぞれ最小操作回数で移動させるとき、最も操作回数が必要になるのは、青エリアの境界から一番遠い位置にある要素 です。
一方、青エリア外→内の移動については、一番右にある要素 が青エリアの境界から最も遠いので、操作回数が最大です。
最適解を達成するには少なくとも、これら 要素を青エリア内外で移動させるだけの操作回数が必要になります。これら 要素だけの移動は、
- 要素 を青エリア内の右端に移動させる( swap)
- 要素 を青エリア外の左端に移動させる( swap)
- 青エリアの狭間でswap
とすることで、最小操作回数で達成できます。
操作回数は
- (要素 のindex) - (要素 のindex)
と、計算で求められます。
よって、先の最適解では他の要素も移動させなければならないので、操作回数は 以上だと分かります。
ここで、目的達成のためには、すべての要素を移動させる必要はありません。
スコアを でも大きくすれば良いのですから、
- 青エリア内のある 要素と、それよりも大きい、外側にある 要素を移動させる
だけで良いです。
どのような最適解を考えても、このような関係にある 要素は必ず存在します。(存在しなければスコアが増加しないため。簡単な証明は注釈に。)*1
先ほどのケースだと、例えば、 と だけを入れ替えれば良いです。
この場合の最小操作回数は先ほどと同様に考えて、
- (要素 のindex) - (要素 のindex)
で求められます。
これは先の最適解の操作回数の下限である 以下です。
つまり、目的達成のためには、
- 青エリア内のある 要素と、それよりも大きい、外側にある 要素を移動させる
だけで良いので、そのうち操作回数が最小になるものを見つければ良いです。
すなわち、 を満たす に対し、 を求める問題になります。
実装
という要素とindexのペアを昇順に並べ、舐めていきます。
詳しい実装は公式解説を参照してください。
補足
実装において
- なぜ ではなく としてペアをつくるのか?
という疑問に対しては、次のケースで考えてみると分かると思います。
一言で言うと、「青エリア内外で等しい要素がある場合、舐めるときに青エリア外にある方を優先して舐めたいため」です。