🍣

【まとめ】アルゴリズム的思考力が身につく!Atcoder ②

2024/01/29に公開

アルゴリズムの勉強のために以下の本を読んだので、読んでいた時のメモ
上級編
中級編は前記事

https://www.kadokawa.co.jp/product/321904000758/

再帰関数と全探索

関数の中で同じ関数を呼び出す関数
終了条件必ずつける
N重のfor loop→コード書くのが難しい
→同じ処理(つまり再帰関数)をfor i in Nすればいいよね。

ナップザック問題

重さWの中で品物の価値の和を最大化する問題
品物を選ぶか選ばないかを0,1で表して0と1の数列を作ると、2^N乗通りの計算が必要となる
N重のfor文はNが確定してないと書けない
→再帰関数 or itertools.product(Python3)
0,1だけで表される数列は2進数とも取れる→bit全探索

幅優先探索(BFS)

グラフの始点に近いところから探す探索方法
幅優先を使うと、始点からある頂点までの最短経路が探せる
使うデータ

  • que: キュー これから探索する予定の頂点
  • dist: 配列 探索終了時では、dist[v]は始点から頂点vへの最短経路 長さはグラフの頂点数N

キューは、Fist in Fist Out(FIFO)
→最初にqueに入れた(始点に近い)頂点から先に取り出す(幅優先!)
グラフの辺の数をMとすると、計算量はO(M)

ダイクストラ法

BFSは頂点間の距離がすべて等しい場合に使える。
等しくない場合にはダイクストラ法が使える。
BFSを拡張して優先度付きキューにすると、ダイクストラ法になる

https://qiita.com/zk_phi/items/d93f670544e4b9816ed0

動的計画法(DP)

グラフの各辺に重みを付けたグラフ→ 重み付きグラフ
重み付きグラフの場合は、幅優先探索よりも動的計画法を使う
再帰関数で全探索
→ 同じ再帰関数rec(i)を何度も計算しているのが無駄
→ 同じ計算は2度しないようにメモしておく(キャッシュ)
→ 動的計画法dp[i]=rec(i) 答えをメモ!

貪欲法

Nステップからなる意思決定を最適化
→ 一般的には動的計画法が使われる
→ 各ステップの最善の選択を繰り返す方法もある(貪欲法)
しかし、将来的に最適になる選択を切り捨てている可能性があるため、貪欲法が常に最適とは限らない
→ どのような場面で貪欲法が使えるかを見極めるのが大切
以下のような構造の時で有用

  • 交換しても悪化しない
  • 後によいものを残す
  • 端から決まっていく

Discussion