Submit Search
実践・最強最速のアルゴリズム勉強会 第二回講義資料(ワークスアプリケーションズ & AtCoder)
•
85 likes
•
31,454 views
A
AtCoder Inc.
Follow
実践・最強最速のアルゴリズム勉強会第二回 講義資料
Read less
Read more
1 of 107
Download now
Downloaded 300 times
More Related Content
実践・最強最速のアルゴリズム勉強会 第二回講義資料(ワークスアプリケーションズ & AtCoder)
1.
実践・最強最速のアルゴリズム勉強会 第二回 講義資料 AtCoder株式会社 代表取締役 高橋
直大 2014/3/16 1
2.
はじめに! • 本講義では、ソースコードを扱います。 • 前面の資料だけでは見えづらいかもしれないので、 手元で閲覧できるようにしましょう。 •
URLはこちらから – http://www.slideshare.net/chokudai/wap-atcoder2 – URLが打ちづらい場合は、Twitter: @chokudaiの最新発言 から飛べるようにしておきます。 • フォローもしてね!!! 2014/3/16 2
3.
©AtCoder Inc. All
rights reserved. 3 目次 1. 勉強会の流れ 2. 競技プログラミングって? 3. シミュレーション問題 4. 全探索問題 5. 本日のまとめ 2014/3/16 3
4.
©AtCoder Inc. All
rights reserved. 4 勉強会の流れ 1. 勉強会の日程 2. 1日の流れ 2014/3/16 4
5.
勉強会の日程 1日目 シミュレーションと全探索 2日目 色々な全探索 3日目
動的計画法とメモ化再帰 4日目 動的計画法と計算量を減らす工夫 5日目 難問に挑戦! 2014/3/16 5
6.
1日の流れ 講義 実践演習 2014/3/16 6
7.
1日の流れ • 基礎的なアルゴリズムを学ぶ • 必要な知識を補う講義 •
実際に問題例を見る • コードでの表現方法を覚える実践 • 自分で問題を解いてみる! • コードを書いて理解を深める演習 2014/3/16 7
8.
1日の流れ • 演習について – 実力差があると思うので、暇な時間が出来る人、ついていけな い人、出ると思います。 •
どうしようもないので、早い人は支援に回ってもらえると嬉しいです! – 解らないことがあったら、#WAP_AtCoderでTwitterに投稿! • 多分早く終わった人が質問回答してくれます。 • 具体例はこんな感じ – 「今やってる問題どれですか!」 – 「この解答のWAが取れません! http:// ~~」 – 「コンパイルエラー出るよーなんでー>< http:// ~~」 – とりあえずコードが書けてたら、間違ってても提出してURLを貼りつけよう – もちろん、手を上げて質問してくれてもOK! • 回りきれる範囲では聞きに行きます。 2014/3/16 8
9.
©AtCoder Inc. All
rights reserved. 9 今日の流れ 1. 前回までの復習 2. 今回やること 2014/3/16 9
10.
前回までの復習 • シミュレーション問題 – 単純なシミュレーション問題 –
繰り返しのあるシミュレーション問題 • どちらも、言われたことを素直に実装! • 全探索問題 – 全探索問題のタイプ分け • Forループだけで書ける全探索・書けない全探索 • Forループで書ける全探索をマスターする! 2014/3/16 10
11.
今回やること • 全探索問題 – 単純なforループで書けない全探索問題をイメージできる ようにしよう! •
どんな風に列挙すれば良いのか – さらに、実際に実装できるようにしよう! • 幅優先探索 • 深さ優先探索 – その他便利な探索方法を覚えよう! • Bitを利用した二分木に対する全列挙 • 順列に対する全列挙 ←時間があれば。 2014/3/16 11
12.
©AtCoder Inc. All
rights reserved. 12 今日の講義 1. どうやって探索するの? 2. 深さ優先探索 3. 幅優先探索 4. 深さ優先探索と幅優先探索の違い 5. 色々な探索 2014/3/16 12
13.
©AtCoder Inc. All
rights reserved. 13 どうやって探索するの? 1. For文以外の探索が必要になるケース 2. 探索する方法 2014/3/16 13
14.
For文以外の探索が必要になるケース • 前回までの復習 – 色々な全探索の種類 –
かんたん • 1から100000までの数字の中に、素数がいくつあるか答えなさい。 • アルファベット3文字で構成された文字列のうち、画数が5以下で書 けるものが何通りあるか求めなさい。 • 10個のりんごを、3人で分けます。分け方が何通りあるかを答えなさ い。 – むずかしい • 将棋の駒の香車があります。1マス目から9マス目まで移動する時、2 つ飛ばしで移動する動きがないパターンの数を答えなさい。 • 3*3のパネルに、9種類の数字を1つずつ置くことが出来ます。魔法陣 が作れるかどうかを判定しなさい。 • 10問の○×クイズを連続して解きます。6問以上正解して、なおかつ 3問連続正解を含む、解答の仕方が何通りあるか答えなさい。 2014/3/16 14
15.
For文以外の探索が必要になるケース • 何が「かんたん」と「むずかしい」の差? – 少ないforループで書けるか否か! •
例えば、この2つは大きく違う! – N個のりんごを、3人で分けます。 • 3個のforループで表現できる – 10個のりんごを、N人で分けます。 • N個のforループで表現できる? – Nが入力で与えられたらどうしようもない。 2014/3/16 15
16.
For文以外の探索が必要になるケース • N個のりんごを、3人で分けます。 • 仮にN=5とする 2014/3/16
16 0 1 2 3 4 5 : : : : : : : : : : Nがいくつになろうと、深さは2まで。 だからforループ2回で探索できる!
17.
For文以外の探索が必要になるケース • 5個のりんごを、N人で分けます。 • 仮にN=4とする 2014/3/16
17 0 1 2 3 4 5 : : : : : : : : : : Nによって深さが変わってしまう。 Forループをたくさん書かないといけない。 : : : : : :
18.
For文以外の探索が必要になるケース • 難しい全探索の解き方 – 単純なforループでは、最早上手く解くことは出来ない。 –
forループよりももっと汎用性の高い、他の実装方法をしな くてはならない! 2014/3/16 18
19.
For文以外の探索が必要になるケース • 要するに、こんな感じの図を書いた時に、この○を 全て辿れるようなアルゴリズムを考えれば良い。 2014/3/16 19 0 1
2 3 4 5 : : : : : : : : : : Nによって深さが変わってしまう。 Forループをたくさん書かないといけない。 : : : : : :
20.
探索する方法 • 辿る方法として有名なものは、この2つ! – 深さ優先探索 –
幅優先探索 • 今回は、この2つを徹底的にマスターします! 2014/3/16 20
21.
©AtCoder Inc. All
rights reserved. 21 深さ優先探索 1. 深さ優先探索って? 2. 深さ優先探索の実装 3. 深さ優先探索が有効な場面 2014/3/16 21
22.
深さ優先探索って? • 例えばこんな図があったとしましょう。 2014/3/16 22
23.
深さ優先探索って? • 深さ優先探索は、こんな探索方法 2014/3/16 23 1 2
6 3 5 7 4 8 109
24.
深さ優先探索って? • 深さ優先探索は、こんな探索方法 – 一筆書きで探索します! 2014/3/16
24 1 2 6 3 5 7 4 8 109
25.
深さ優先探索って? • 再帰関数を使った探索手法 – 本当は使わないでも書けるけど、使うのが一般的 •
慣れるまでは大変だが、慣れれば極めて直感的に 書ける。 • 実装イメージは以下のような感じ int dfs(今の状態){ int ret = 0; for( … ) ret += dfs(次の状態); return ret; } 2014/3/16 25
26.
深さ優先探索の実装 • 問題 – M個のリンゴを、N人で分ける時、分け方が何通りある か? •
ここで作るべき関数を、こんな感じで書いてあげる。 – Int dfs(int M, int N) • この関数を使えば、M個のりんごをN人で分けた時の、組み合わ せの個数が解る、という前提を置く。 2014/3/16 26
27.
深さ優先探索の実装 • Int dfs(int
M, int N)の中身について – N > 1のとき • まだりんごを配るべき人が二人以上残っている。 • 一人目の人に対して、「りんごを0個あげる」「りんごを1個あげる」 「りんごを2個あげる」・・・「りんごをM個あげる」の全通りを試し、 その結果の和を取りたい。 • dfs(M, N) = dfs(0, N-1) + dfs(1, N-1) + … + dfs(M, N-1)と表せる – N = 1のとき • りんごを配るべき人が一人しか残っていない。 • 残りのりんごを全てあげる以外の選択肢がない。 – つまり、パターンは1通り 2014/3/16 27
28.
深さ優先探索の実装 • 例:4つのりんごを3人で分ける。 2014/3/16 28 dfs(4,3) dfs(4,2)
dfs(3,2) dfs(2,2) dfs(1,2) dfs(0,2) 4,1 3,1 2,1 1,1 0,1 3,1 2,1 1,1 0,1 2,1 1,1 0,1
29.
深さ優先探索の実装 • 例:4つのりんごを3人で分ける。 2014/3/16 29 dfs(4,3) dfs(4,2)
dfs(3,2) dfs(2,2) dfs(1,2) dfs(0,2) 4,1 3,1 2,1 1,1 0,1 3,1 2,1 1,1 0,1 2,1 1,1 0,1
30.
深さ優先探索の実装 • 例:4つのりんごを3人で分ける。 2014/3/16 30 dfs(4,3) dfs(4,2)
dfs(3,2) dfs(2,2) dfs(1,2) dfs(0,2) 4,1 3,1 2,1 1,1 0,1 3,1 2,1 1,1 0,1 2,1 1,1 0,1 1 1 1 1 1
31.
深さ優先探索の実装 • 例:4つのりんごを3人で分ける。 2014/3/16 31 dfs(4,3) dfs(4,2)
dfs(3,2) dfs(2,2) dfs(1,2) dfs(0,2) 4,1 3,1 2,1 1,1 0,1 3,1 2,1 1,1 0,1 2,1 1,1 0,1 1 1 1 1 1 5
32.
深さ優先探索の実装 • ソースコード 2014/3/16 32
33.
深さ優先探索の実装 実践 • ARC001
C問題 パズルのお手伝い – http://arc001.contest.atcoder.jp/tasks/arc001_3 – 問題概要 • 8*8のマス目が与えられます。8個の駒を、「たて」「よこ」「ななめ」 で同じ列に存在しないように配置したいです。最初に3個配置され ているので、残りのマスを埋めなさい。無理ならNo Answerと出力 2014/3/16 33
34.
深さ優先探索の実装 実践 • 解き方 –
まず全てのマスに番号をつける 2014/3/16 34 0 1 2 3 4 5 6 7 8 61 62 63
35.
深さ優先探索の実装 実践 • 解き方 –
まず全てのマスに番号をつける – 1番から順番に、「置く」「置かない」を全て試す。 • 既に他の駒と干渉してしまって置けない場合は諦める。 – 具体的には、以下のような関数を作る • bool dfs(今見ているマス, 残りマス数, 今の盤面) – 返り値は、「完成させられたか否か」 • これを用いて、深さ優先探索を行う。 • 「置く」「置かない」を試す。 – すでに置けない場所なら「置く」は試さない。 – 絶対に置かないといけないなら「置かない」は試さない。 2014/3/16 35
36.
深さ優先探索の実装 実践 • 探索のイメージ 2014/3/16
36
37.
深さ優先探索の実装 実践 • ソースコード –
http://arc001.contest.atcoder.jp/submissions/145104 2014/3/16 37
38.
深さ優先探索の実装 実践 • ソースコード 2014/3/16
38
39.
深さ優先探索の実装 実践 • ソースコード 2014/3/16
39
40.
深さ優先探索の実装 実践 • ソースコード 2014/3/16
40
41.
深さ優先探索の実装 実践 • ソースコード 2014/3/16
41
42.
深さ優先探索の実装 実践 • 解き方2 –
1行に1個しか置かないということは、各行に対して、どの 列に置くかを割り当てれば良い。 • 長さ8の順列を全列挙するのも良い – 割り当てた駒が、正しく置けているかを確かめていく。 – 用意する再帰関数は、以下のような感じ。 • dfs(今見ている場所, 盤面の状況) 2014/3/16 42
43.
深さ優先探索の実装 実践 • 探索のイメージ 2014/3/16
43
44.
深さ優先探索の実装 実践 • ソースコード –
http://arc001.contest.atcoder.jp/submissions/145107 2014/3/16 44
45.
深さ優先探索の実装 実践 • ソースコード 2014/3/16
45
46.
深さ優先探索の実装 実践 • おまけ –
盤面の状態を引数に入れたが、これは外に出しても良い • 覚えておくとたまに便利 2014/3/16 46
47.
深さ優先探索の実装 実践 • 解き方3 –
ボードサイズが8パターンなんだから、8個forループを置 けば良い!!! • やめましょう。 • でも意外と実装短めだったりします。 2014/3/16 47
48.
深さ優先探索の実装 演習 • ARC009
C問題 高橋君、24歳 – http://arc009.contest.atcoder.jp/tasks/arc009_3 – 今回解くのは、これの部分点(small部分) – Largeが採点されないように、以下のような記述を • If(N>8) return; • 問題概要 – 高橋君はN枚の手紙を出した。 – でもM枚は違う人に出してしまったらしい。 – 出してしまった手紙の組み合わせとして、あり得るものの 組み合わせの個数を答えなさい。 2014/3/16 48
49.
深さ優先探索の実装 演習 • 暇な人は以下の問題にチャレンジ! •
ARC014 C問題 魂の還る場所 – http://arc014.contest.atcoder.jp/tasks/arc014_3 – 部分点のみ • オリジナル問題 – 3*3の魔法陣がいくつ存在するか数え上げなさい。 – ただし、反転・90度回転で同じとなる魔法陣は、同じもの と見做します。 – それが出来たら4*4を頑張ってみてください。 2014/3/16 49
50.
深さ優先探索の実装 演習 • 解き方 –
まずは全列挙のイメージを持とう! • どうやって全列挙して、どういう図になるかを考えるのが一番大 事! – 今回のケース • 1番目の人が、手紙aを貰う(aを全探索) – 2番目の人が、手紙bを貰う(bを全探索) » 3番目の人が・・・ • こんな感じの全列挙が浮かぶはず! 2014/3/16 50
51.
深さ優先探索の実装 演習 • 解き方
イメージ図 • 3人のパターン 2014/3/16 51 0 0 1 1 2 0 1 2 2 0 2 1 2 3 3 2 0 1 2 0 0 0 0 1 1 1 1 2 2 2 2
52.
深さ優先探索の実装 演習 • 解き方 –
さっきの図のような探索をするために必要なもの • 誰に手紙を渡すか考えないといけない – 今誰に渡そうとしているかの情報 • どの手紙を渡すかを全列挙しなければならない – どの手紙をすでに渡しているかの情報 • 間違った手紙が現在いくつ渡されているかが必要 – この3つを引数に持たせた再帰関数を考えれば、解けそ うであることが予想できる。 2014/3/16 52
53.
深さ優先探索の実装 演習 • 解き方 –
誰宛ての手紙が誰に届いたかを全列挙する – それぞれに対し、いくつ間違っているかを列挙し、Kと等し くなった数を返す。 – 作る関数はこんな感じ。 • int dfs(int pos, boolean[] used, int nokori) – pos あと何人残っているか – used どの友人の手紙をすでに使ったか – nokori 間違っている人数は残り何人か。 » nokoriはなくても、具体的な順列を持って置くことで、最後に全て計算 することで実装することは可能 » 途中で計算すると、具体的な順列を持っていなくても良くなる。 2014/3/16 53
54.
深さ優先探索の実装 演習 • ソースコード –
http://arc009.contest.atcoder.jp/submissions/145109 2014/3/16 54
55.
深さ優先探索の実装 演習 • ソースコード 2014/3/16
55
56.
深さ優先探索の実装 演習 • ソースコード 2014/3/16
56
57.
深さ優先探索が有効な場面 • とにかく全列挙がしたい時に使おう! – 「有限のもの」に対する全列挙ツールとしては最強です。 –
これだけ知っとけば問題ないです。 • 「無限のもの」に対してはちょっと弱い。 – 無限にループしちゃいます。 – そもそも全列挙が無理なので、余り気にしないで良い。 – しかし、「全探索で解ける」と巷で言われている問題には、 「全てを列挙出来るわけではない」問題も挙げられる。 • この辺りは、幅優先探索での話で 2014/3/16 57
58.
©AtCoder Inc. All
rights reserved. 58 幅優先探索 1. 幅優先探索って? 2. 幅優先探索の実装 3. 幅優先探索が有効な場面 2014/3/16 58
59.
幅優先探索って? • 例えばこんな図があったとしましょう。 2014/3/16 59
60.
幅優先探索って? • 幅優先探索は、こんな探索方法 2014/3/16 60 1 2
3 4 5 6 7 8 109
61.
幅優先探索って? • 幅優先探索は、こんな探索方法 – 近い順に探索する! 2014/3/16
61 1 2 3 4 5 6 7 8 109
62.
幅優先探索って? • キューとループを使って、近い順から – キューは、変数をたくさん放り込むと、放り込んだ順から 取り出せるもの、と解釈してもらえばOKです。 –
実装のイメージは下のような感じ Queue<int> q = new Queue<int>(); q.push(初期状態); while(!q.isEmpty()){ int now = q.poll(); //今の状態を取り出す for( … ) q.add(次の状態); } 2014/3/16 62
63.
幅優先探索の実装 実践 • ARC005
C問題 器物損壊!高橋君 – http://arc005.contest.atcoder.jp/tasks/arc005_3 • 問題概要 – 2次元空間の迷路のようなものが与えられる – 壁を2回まで壊すことが出来る – スタートからゴールに辿り着くことが出来るか出力せよ。 2014/3/16 63
64.
幅優先探索の実装 実践 • やり方 –
幅優先探索で、0回の破壊で行ける範囲、及び1回目に破 壊する壁を全て列挙する。 – 幅優先探索で、1回目の破壊で行ける範囲、及び2回目に 破壊する壁を全て列挙する。 – 幅優先探索で、2回目の破壊で行ける範囲を列挙する。 – 行ける範囲にGがあればYES 2014/3/16 64
65.
幅優先探索の実装 実践 • 幅優先部分のやり方 –
Queue<Integer> nowq; <- 今調べるもの – Queue<Integer> nextq; <- 次ターンに調べるもの for(int i = 0; i < 3; i++){ nextq = new Queue<Integer>(); while(nowq.isEmpty()){ int now = nowq.poll(); for(…) ここで次の状態を列挙する } } 2014/3/16 65
66.
幅優先探索の実装 実践 • ソースコード –
http://arc005.contest.atcoder.jp/submissions/145134 2014/3/16 66
67.
幅優先探索の実装 実践 • ソースコード 2014/3/16
67
68.
幅優先探索の実装 実践 • ソースコード 2014/3/16
68
69.
幅優先探索の実装 実践 • ソースコード 2014/3/16
69
70.
幅優先探索の実装 実践 • ソースコード 2014/3/16
70
71.
幅優先探索の実装 演習 • ARC001
B問題 リモコン – http://arc001.contest.atcoder.jp/tasks/arc001_2 • 問題概要 – エアコンの温度を、A度からB度に変更したい – エアコンのリモコンには、6つのボタンがついている。 • 温度を1, 5, 10度上げる • 温度を1, 5, 10度下げる – 温度をBにするまでに、必要なボタンを押す回数 2014/3/16 71
72.
幅優先探索の実装 演習 • この問題の難しい点 –
「全探索」で解ける問題だが、「パターンの全列挙」が出来 るわけではない。 • リモコンの押し方は無限通り存在する。 • 深さ優先探索だと、ずっとループしてしまう! • 39 -> 40 -> 39 -> 40 -> 39 -> 40 -> 39 -> …… • ループしないように対策しても難しい。 – だが、ボタンを押す回数を制限してしまえば、組み合わせ は有限通りしか存在しない。 – よって、押す回数が少ないパターンから順番に調べていく 2014/3/16 72
73.
幅優先探索の実装 演習 • 暇な人は次の問題に挑戦! •
ARC015 C問題 変わった単位 – http://arc015.contest.atcoder.jp/tasks/arc015_3 2014/3/16 73
74.
幅優先探索の実装 演習 • やりかた –
最初に、キューに、初期状態Aを入れておく。 – キューに入っているものを順番に取り出す。 • そこから遷移出来る温度を全て取り出す。 • もし初めて辿り着いた温度であれば、遷移回数をメモリに保存し た上で、キューに入れる。 – 目的の温度に辿り着いたら、遷移回数を出力する。 2014/3/16 74
75.
幅優先探索の実装 演習 • ソースコード –
http://arc001.contest.atcoder.jp/submissions/145113 2014/3/16 75
76.
幅優先探索の実装 演習 • ソースコード 2014/3/16
76
77.
©AtCoder Inc. All
rights reserved. 77 深さ優先探索と幅優先探索の違い 2014/3/16 77
78.
深さ優先探索と幅優先探索の違い • 深さ優先探索 – 見つかった順番に調べていく •
辞書順最小を調べたり、とにかく全列挙したい時に適している! – 再帰関数を使って実装 • 途中までの計算結果などを使いやすい • 解の復元が簡単! • 幅優先探索 – 近い順に調べていく • 最短距離や、最も短いものを探すのに適している! – whileでのループとキューを使って実装 • 慣れれば実装は簡単? • 解の復元は大変 2014/3/16 78
79.
©AtCoder Inc. All
rights reserved. 79 休憩! 再開は15:40から! 2014/3/16 79
80.
©AtCoder Inc. All
rights reserved. 80 色々な探索 1. Bitを利用した二分木の全探索 2. 順列に対する全探索 2014/3/16 80
81.
©AtCoder Inc. All
rights reserved. 81 BITを利用した二分木の全探索 1. bitをいかにして使うか? 2. Bitの実装 2014/3/16 81
82.
Bitを利用した二分木の全探索 • 問題 • OとXのみで構成されたN文字の文字列を列挙して、 ~~~しなさい。 –
深さ優先探索で行けるけど、再帰関数書くの大変・・・。 • 再帰関数を書かなくても、for文だけで書けてしま う! 2014/3/16 82
83.
Bitを利用した二分木の全探索 • 例えば、OとXのみで構成された5文字の文字列の全 列挙をする時 – for(int
i=0; i<32;i++) – 実は、このfor文で全列挙出来てしまう 2014/3/16 83
84.
Bitを利用した二分木の全探索 • 整数を2進数で表す – 0
… 00000 – 1 … 00001 – 2 … 00010 – 3 … 00011 – 4 … 00100 – ….. – 31 … 11111 • 0から31までの数字はこんな感じ 2014/3/16 84
85.
Bitを利用した二分木の全探索 • 整数を2進数で表す – 0
… 00000 … OOOOO – 1 … 00001 … OOOOX – 2 … 00010 … OOOXO – 3 … 00011 … OOOXX – 4 … 00100 … OOXOO – ….. – 31 … 11111 … XXXXX • 0から31までの数字はこんな感じ – 0,1を、O,Xに対応させてしまえば良い! 2014/3/16 85
86.
Bitを利用した二分木の全探索 • 整数のk桁目のbitを、k番目の分岐に対する選択と 解釈することにより、forループで処理可能になる! – ○×ゲームの解答を10回行った結果の全列挙 •
k番目のbitが0ならk問目は○、そうでなければ× – 香車の進み方の全列挙 • k番目のbitが0ならkマス目には止まらない。そうでなければ止ま る • 他にも、整数のbitで表せるものはたくさんある! – 先ほどの手紙問題だと、「誰に手紙を渡したか」を整数1 つで持つことも可能 2014/3/16 86
87.
Bitを利用した二分木の全探索 • 具体的な実装例 2014/3/16 87
88.
Bitを利用した二分木の全探索 • 具体的な実装例 – (1
<< N) • 2のN乗。「2択がN回ある場合」の要素数。 – ((i >> j) % 2) • iに対する、j番目のbit情報を取り出す。 » jは0から数えます。0-indexedです。 • 例えば、i -> 12( = 1100)なら、 – (12 >> 1) -> 6(110) – (12 >> 2) -> 3(11) – (12 >> 3) -> 1(1) • と、こんな感じで、右からj番目の要素を取り出せる 2014/3/16 88
89.
Bitを利用した二分木の全探索 実践 • ABC002
D問題 派閥 – http://abc002.contest.atcoder.jp/tasks/abc002_4 • 問題概要 – 12人の友人関係が与えられる – 全員が全員を友達だと思っているグループのうち、最大 なものを作成したい – そのグループの人数を出力せよ 2014/3/16 89
90.
Bitを利用した二分木の全探索 実践 • やり方 –
グループの候補となる、人の集合を全て列挙する • それらのグループに対して、本当に人が友達同士になっているか どうか確認を行う。 • 友達同士になっていれば、答えの最大値を更新する。 – これは、深さ優先探索での列挙も出来るが、bitを使った for文での列挙の方がずっと楽! 2014/3/16 90
91.
Bitを利用した二分木の全探索 実践 • ソースコード –
http://abc002.contest.atcoder.jp/submissions/145126 2014/3/16 91
92.
Bitを利用した二分木の全探索 実践 • ソースコード 2014/3/16
92
93.
Bitを利用した二分木の全探索 演習 • ARC007
C問題 節約生活 – http://arc007.contest.atcoder.jp/tasks/arc007_3 • 問題概要 – 一定の周期で、映ったり映らなかったりを繰り返すテレビ が複数台存在する – 全ての瞬間において、いずれかのテレビが映っているよう にしたい – 必要なテレビの個数はいくつか? 2014/3/16 93
94.
Bitを利用した二分木の全探索 演習 • 問題概要 –
例 oxoxx → 3つのテレビが必要 2014/3/16 94
95.
Bitを利用した二分木の全探索 演習 • 暇な人は以下の問題にチャレンジ! •
ARC014 C問題 魂の還る場所 – http://arc014.contest.atcoder.jp/tasks/arc014_3 • 部分点まで • ARC017 C問題 無駄なものが嫌いな人 – http://arc017.contest.atcoder.jp/tasks/arc017_3 • そのままだと間に合わないので工夫が必要 2014/3/16 95
96.
Bitを利用した二分木の全探索 演習 • 解き方 –
テレビの再生時間をちょっとずつズラせば良い。 • 0~9秒ずらす – 10種類しかない! – 10種類のテレビの使う・使わないの集合は、1024回のfor ループで書き表すことが出来る。 • 各部分集合に対して、全てのタイミングでテレビが映っているかど うか調べれば良い。 2014/3/16 96
97.
Bitを利用した二分木の全探索 演習 • ソースコード –
http://arc007.contest.atcoder.jp/submissions/145128 2014/3/16 97
98.
Bitを利用した二分木の全探索 演習 • ソースコード 2014/3/16
98
99.
Bitを利用した二分木の全探索 演習 • ソースコード 2014/3/16
99
100.
Bitを利用した二分木の全探索 演習 • おまけ •
探索を整数のbit列で手抜きしたが、あるタイミング にテレビが映っていたかの判定も、bit列を使ってす ることが出来る。 2014/3/16 100
101.
Bitを利用した二分木の全探索 演習 • ソースコード2 –
http://arc007.contest.atcoder.jp/submissions/145135 2014/3/16 101
102.
Bitを利用した二分木の全探索 演習 • ソースコード2 2014/3/16
102
103.
©AtCoder Inc. All
rights reserved. 103 順列に対する列挙 2014/3/16 103
104.
順列に対する列挙 • 順列を列挙したい時、結構あると思います。 – {1,2,3}に対する列挙 •
{1,2,3}, {1,3,2}, {2,1,3}, {2,3,1}, {3,1,2}, {3,2,1} – {1,2,2}に対する列挙 • {1,2,2}, {2,1,2}, {2,2,1} • これらは、深さ優先探索を用いれば、問題なく列挙 出来る。 • でも、深さ優先探索を組むのは結構面倒! 2014/3/16 104
105.
順列に対する列挙 • C++では順列の列挙は簡単? – next_permutationという、順列の列挙に役立つ便利なライ ブラリが入っている •
じゃあJavaは? – 便利なライブラリがないので、自分で書いておきましょう。 – さっき手紙の問題で書いたね!やったね! 2014/3/16 105
106.
©AtCoder Inc. All
rights reserved. 106 本日のまとめ 2014/3/16 106
107.
本日のまとめ • あらゆるものを全列挙可能な、2つの探索方法 – 深さ優先探索 –
幅優先探索 – この2つをマスターすれば、全探索問題は怖くない! • 全列挙を楽にする、2つのツール – bitを使った、二分木の全探索 – 順列に対する全探索 • これらが理解できていればOKです! 2014/3/16 107
Download