A - Pyramid Sorting 解説 by k_k_pyrhon

ほぼ最適化を行わない貪欲解

貪欲解で比較的上位に入ってしまったので、解説に初挑戦してみたいと思います。上級者ではないので迂闊なことは言えませんが、今回はあまり難しいことを考えすぎなかったために良い結果がでたのかな…?と思っています。
[2023-06-26 08:52追記]
[2023-06-26 21:27修正]

単純な貪欲解

今回のスコア計算を見るとやらねばいけないことは以下の2つだと考えられます。

  • 全てのボールを条件に従わせねばならない(条件に違反している時点でスコアが50000以下になってしまうため)
  • 出来る限り操作回数を減らさねばならない

ここでは1つ目の条件を貪欲に実装してみます。条件に従わせるには、感覚的に言うならば小さい数字のボールが上の方に、大きい数字のボールが下の方に行けば良さそうだという事が分かります。

なのでその通りにしてやればよいです。小さい数字のボールから順に処理して、位置を固定させてゆくことで楽に実装が可能です。小さい数字から順に上に移動させてやるだけなので、考えることも少ないです。横移動は要りません。
以下のリンクが実装例です。単に貪欲法を書いただけですが、それでも十分高速な操作方法となります。

貪欲解[スコア : 13143540]

少し工夫を加える

処理する際に、交換する相手により大きい数字のボールを選ぶ (小さい数字のボールを上へ運ぶ際により大きい数字のボールを選んで交換する) ことでスコアの改善が可能です。細かい部分は割愛しますが、大きい数字のボールを下の方へ運ぶに越したことはないという事は簡単に考え得ることかと思います。(とはいえ、大きな改善にはつながりませんでしたが…)

改良版[スコア : 13426585]

さて、これ以上の最適化は思いつけなかったため難しい解法は他の方に任せてこの解説は以上とさせていただきます…
もう少し自分の考察を言うと、実は制約を満たしているならば小さい数字のボールが最下層にあったとしてもよいという事があったりします。次のコード[python]が出力する入力例が参考になるかもしれません…

for i in range(30):
    k = i
    a = []
    for j in range(i+1):
        a.append(k)
        k += 30-j-1
    print(*a)

追記

上記のコードではボールの位置を固定するか否か判定する評価関数をDFSによって実装していますが、実は親要素との比較のみによって判定が可能です。
ボール\(i\)の操作を行っている時点で\(i-1\)番目までのボールはすでに固定済みであるため、この方法が使えます。なんと無駄なことをやっていたのでしょうか……

最適化した評価関数によるコード[置換は改良版]
[2023-06-26 08:52追記]
[2023-06-26 21:27修正]

投稿日時:
最終更新: