Successfully reported this slideshow.
Your SlideShare is downloading. ×

競技プログラミング練習会2015 Normal 第2回

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 28 Ad

More Related Content

Recently uploaded (20)

Advertisement

競技プログラミング練習会2015 Normal 第2回

  1. 1. 2015/04/17 長嶺英朗(ID:hnagamin) 競技プログラミング練習会 2015 Normal 第2回
  2. 2. 目次 ● スタックとキュー ● 全探索 – 幅優先探索 – 深さ優先探索 ● 累積和
  3. 3. データ構造 ● データ構造は多数のデータをある秩序に従って保 存しておくための構造です – 例) 配列、ハッシュテーブル、木、スタック、キュー… ● データ構造には様々な種類があり、それぞれ得意な ことと不得意なこと、可能なことと不可能なことがあ ります ● 今日はスタックとキューの話をします
  4. 4. スタック ● 「後入れ先出し」 (Last In, First Out)のデータ構造 ● 次のことがO(1)でできる ● push: 先頭に要素を追加する ● pop: 先頭の要素を取り出す ● 本の山みたいなイメージ push pop
  5. 5. キュー ● 「先入れ先出し」 (First In, First Out)のデータ構造 ● 次のことがO(1)でできる ● enqueue: 先頭に要素を追加する ● dequeue: 末尾の要素を取り出す ● 店の行列的なイメージ enqueue dequeue
  6. 6. スタックを使う問題の例 http://poj.org/problem?id=2559
  7. 7. 全探索
  8. 8. 全探索 ● いくつかの組合せの中からある特定のものを探す とき、考えるべき組合せが比較的少ない場合にはそ れらを全て調べてしまうのが有効なことがある ● 「比較的少ない」: 106通りくらい
  9. 9. 全探索が有効な例 ● 3×3魔法陣の解の個数を求める ● 3x3マスに1~9の数字を入れて魔法陣か確かめる ● 考えるべき組合せは9!通り ● 9! = 362880 < 106 ● 間に合う 2 9 4 7 5 3 6 1 8
  10. 10. 全探索が有効な例 ● 8クイーン問題の解のひとつを求める ● 8x8チェス盤に8つのクイーンを置く ● どのクイーンも他の駒の利きにないよう置く
  11. 11. 8クイーン問題の解の一例 http://ja.wikipedia.org/wiki/エイト・クイーン
  12. 12. 全探索が有効な例 ● 普通に並べると64C8 通り – ちょっと大きい ● 工夫が必要
  13. 13. 全探索が有効な例 ● 普通に並べると64C8 = 4426165368 通り – ちょっと大きい ● 工夫が必要
  14. 14. 全探索が有効な例 ● よく考えると、2つのクイーンは同じ列・同じ行には 並ばない ● {1, 2, ... 8} の順列をクイーンの位置に対応させる ● 8! = 40320 ● 間に合う (7, 5, 3, 1, 6, 8, 2, 4)
  15. 15. 全探索 ● 考えるべき状態を木として扱うことが多い 1 2 3 4 5 1 31 2 1 4 2 1 …
  16. 16. 18 1914 深さ優先探索 ● 葉に到達するまで子要素を探索してから次の子要 素を探索する 1 2 11 15 3 5 8 12 13 16 17 4 6 7 9 10
  17. 17. 深さ優先探索 ● スタックを使って深さ優先探索が実現できる ● まだ探索していない頂点をスタックに積んでから、 スタックから頂点を取り出して深さ優先探索する
  18. 18. 18 1917 幅優先探索 ● 子要素を全て探索してから子要素の子要素を探索 する ● 根に近い順に探索していく 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  19. 19. 幅優先探索 ● キューを使って幅優先探索が実現できる ● 今見ている頂点の子要素を全てキューに突っ込ん でから、キューから頂点を1つ取りだして幅優先探 索する
  20. 20. 深さ優先探索のココがすごい! ● メモリ消費量が幅優先に比べて少ない! ● 再帰を使うことで楽に書ける! – 再帰を使って書くときは、暗黙のうちにコールスタックを 使っている ● 葉に至るまでが長い分枝が存在するとつらい! – 木の深さが有限でない場合終わらないことがある
  21. 21. 幅優先探索のココがすごい! ● ある種の最小解が求まる! – 例えば、頂点として迷路内の座標を設定しゴールに向 かって幅優先探索すると迷路を出るための最短経路が 求まる ● (解があれば)(木の深さが有限でなくても) 必ず見つける! ● メモリを大量に使う!
  22. 22. 累積和
  23. 23. 要求 ● 長さNの配列が与えられて、その中にはN個の数が 格納されている ● q個のクエリ(問題)が与えられるので、それに答える – 問題: 「i番目からj番目までの要素の和を答えよ」 ● N 10≦ 6 , q 10≦ 6
  24. 24. 愚直な解法 ● 各クエリに対して、一つひとつ和を求めていく
  25. 25. 愚直な解法 ● 各クエリに対して、一つひとつ和を求めていく ● O(qN) – 各クエリの処理に最大O(N)回の計算が必要 – クエリはq個 ● qN 10≦ 12 – ちょっと大変
  26. 26. 累積和 ● クエリを処理する前に予めSi = (0番目からi番目ま での要素の和)を求めておく ● 各クエリに対してSj - Si-1を返せば良い 3 1 4 1 5 9 2 63 1 4 1 5 9 2 6
  27. 27. 累積和 ● クエリを処理する前に予めSi = (0番目からi番目ま での要素の和)を求めておく ● 各クエリに対してSj - Si-1を返せば良い 3 1 4 1 5 9 2 6 3 4 8 9 14 23 25 31
  28. 28. 計算量 ● Siを求めるのにO(N) – Si = Si-1 + ai を利用する ● 各クエリに対してO(1) ● 従って、計算量はO(N + q) ● 間に合う

×