いろいろな問題の解説
TRANSCRIPT
いろいろな問題の解説
Masaki Hara
IOI2013直前合宿にて
目次
• Hotter Colder (IOI 2010)
• SaveIt (IOI 2010)
• Parrots (IOI 2011)
• Maze (IOI 2010)
• Disparity (JOI Open 2013)
Hotter Colder
• 1以上N以下の整数を当てたい
• 1以上N以下の整数を質問する
• 直前に聞いたときよりも近いか遠いかがわかる
• できるだけ少ない回数で当てたい
Hotter Colder
• 考察
△ △
直前に質問した位置 今回質問した位置
Hotter Colder
• 考察
△ ● △
直前に質問した位置 今回質問した位置
Colder
Hotter Colder
• 考察
△ ● △
直前に質問した位置 今回質問した位置
Same
Hotter Colder
• 考察
△ ● △
直前に質問した位置 今回質問した位置
Hotter
Hotter Colder
• 考察
Colder Same Hotter
直前に質問した位置 今回質問した位置
Hotter Colder
• 考察
Colder Same Hotter
直前に質問した位置 今回質問した位置
Hotter Colder
• 考察
• 大きいか小さいかがわかる
• 基準: (直前のクエリ + 今回のクエリ) / 2
Hotter Colder
• 普通の「大きい/小さい」問題との違い
Hotter Colder
• 普通の「大きい/小さい」問題との違い
–思った通りの質問ができないことがある
–例1: 直前に5を質問しているときに5との大小
–例2: 直前に5を質問しているときに1との大小
Hotter Colder
• 対策
Hotter Colder
• 対策1: 1クエリに2回質問する
– こうすれば必ず好きな質問ができる
• (50点)
Hotter Colder
• 対策2: 大きい/小さい/同じ の3値情報であることを利用する
– クエリの回数を少しだけ減らせる
• (75点)
Hotter Colder
• 満点解法
Hotter Colder
• 満点解法を考える前に、小さいケースで試す
Hotter Colder
• 問題
– Nが与えられたとき、質問回数を最小化しなさい
– N <= 100
Hotter Colder
• 問題
– Nが与えられたとき、質問回数を最小化しなさい
– N <= 100
• 解答
– DP
– dp[直前の質問,絞り込んだ範囲] =そこからの質問回数
Hotter Colder
• これを実際に実行するとわかること
–十分小さいときは、1→3→5→7の順番で質問するのが良い
–それより大きいときは、𝑁 = 3 ⋅ 2𝑛 − 1のときが一番効率がよい
Hotter Colder
• 𝑁 = 3 ⋅ 2𝑛 − 1 の場合の戦略
Hotter Colder
• 𝑁 = 3 ⋅ 2𝑛 − 1 の場合の戦略
23 − 1個 23 − 1個 23 − 1個
Hotter Colder
• 𝑁 = 3 ⋅ 2𝑛 − 1 の場合の戦略
23 − 1個 23 − 1個 23 − 1個
●
1回目の質問
Hotter Colder
• 𝑁 = 3 ⋅ 2𝑛 − 1 の場合の戦略
23 − 1個 23 − 1個 23 − 1個
● ●
1回目の質問 2回目の質問
Hotter Colder
• 𝑁 = 3 ⋅ 2𝑛 − 1 の場合の戦略
23 − 1個 23 − 1個 23 − 1個
● ●
1回目の質問 2回目の質問
Hotter Colder
• 𝑁 = 3 ⋅ 2𝑛 − 1 の場合の戦略
23 − 1個 23 − 1個 23 − 1個
● ● ●
1回目の質問 2回目の質問 3回目の質問
Hotter Colder
• 𝑁 = 3 ⋅ 2𝑛 − 1 の場合の戦略
23 − 1個 23 − 1個 23 − 1個
● ● ●
1回目の質問 2回目の質問 3回目の質問
両方右側に進んだ場合: 右端で2分探索 (毎回のクエリを必ず実行できる)
Hotter Colder
• 𝑁 = 3 ⋅ 2𝑛 − 1 の場合の戦略
23 − 1個 23 − 1個 23 − 1個
● ● ●
1回目の質問 2回目の質問 3回目の質問
右左の順に進んだ場合: 中央で2分探索 (毎回のクエリを必ず実行できる)
Hotter Colder
• 𝑁 = 3 ⋅ 2𝑛 − 1 の場合の戦略
23 − 1個 23 − 1個 23 − 1個
● ●
1回目の質問 2回目の質問
最初に左に進んだ場合: 左端で2分探索 (2回目の結果は使わない)
Hotter Colder
• これによりどの場合でも均等に効率よくクエリを消費することができる
Hotter Colder
• これによりどの場合でも均等に効率よくクエリを消費することができる
• あとは、境界条件に注意しながらNが一般の場合に拡張する(結構むずい)
Hotter Colder
• Hotter Colder 教訓: 実験は大事
SaveIt
• グラフ中の最短経路を何セットか求めたい
–高々1000個の頂点と高々36個のハブの間の最短経路たちを求めたい
• 通信計算量を小さくしてね
–質問をそのまま送っても、答えをそのまま送っても、損失が出る
SaveIt
• グラフ中の最短経路を何セットか求めたい
–高々1000個の頂点と高々36個のハブの間の最短経路たちを求めたい
• 通信計算量を小さくしてね
–質問をそのまま送っても、答えをそのまま送っても、損失が出る
SaveIt
• 質問をそのまま送る: 25点
• 答えをそのまま送る: 50点
SaveIt
• 共通する構造を抜き出す
• 差分をとることで情報を圧縮する
• ということから、次のように考える
SaveIt
• 全域木を1つ決める
• ハブとの距離は、親との差分で定める
SaveIt
• 全域木を1つ決める
• ハブとの距離は、親との差分で定める
SaveIt
• 全域木を1つ決める
• ハブとの距離は、親との差分で定める
2
1
0
1 1 2
SaveIt
• 全域木を1つ決める
• ハブとの距離は、親との差分で定める
+1 -1
+1 -1 0
SaveIt
• 全域木の情報
– ノード数1000 × ノード番号10bit = 10000bit
• ハブからの距離
–ハブ数36 × ノード数1000 × 差分2bit = 72000bit
SaveIt
• 全域木の情報
– ノード数1000 × ノード番号10bit = 10000bit
• ハブからの距離
–ハブ数35 × ノード数1000 × 差分2bit = 70000bit
• 全域木を、ハブ0からのBFSで構築すると、情報を節約できる
• (75点)
SaveIt
• 全域木の情報
– ノード数1000 × ノード番号10bit = 10000bit
• ハブからの距離
–ハブ数36 × ノード数1000 × 差分5/3bit = 60000bit
• 差分は3通りなので3つまとめて5bitで送れる
• (100点)
Parrots
• オウムに乗せてデータを送る
• データの到着順はわからない
Parrots
• SaveItのパクリっぽい問題
• 何か良い圧縮方法がある?
Parrots
• SaveItのパクリっぽい問題
• 何か良い圧縮方法がある?
Parrots
• SaveItのパクリっぽい問題
• 何か良い圧縮方法がある?
Parrots
• SaveItのパクリっぽい問題
• 何か良い圧縮方法がある?
Parrots
• 単に番号をつければいい
Parrots
• 単に番号をつければいい
状況 番号
オウム0羽 0
オウム1羽(0) 1
: :
オウム1羽(255) 256
オウム2羽(0,0) 257
オウム2羽(0,1) 258
: :
Parrots
• どのように番号をつけるか?
Parrots
• どのように番号をつけるか?
• 前処理: 常に一定数のオウムを送るものとして扱う(送らない分は256というデータだと考える)
Parrots
• どのように番号をつけるか?
• 「y未満の自然数x個からなる単調非減少列」を考えればよい
• これは何個あるか?
Parrots
• どのように番号をつけるか?
• 「y未満の自然数x個からなる単調非減少列」を考えればよい
• これは何個あるか?
• 実は、𝑦 + 𝑥𝑥
個ある
Parrots
• 証明
– 𝑥 = 0のとき、空の列はちょうど1通り。
– 𝑦 = 0のとき、0からなる列はちょうど1通り。
–数列の末尾が𝑦 − 1に等しい場合の列は帰納法
の仮定より𝑦 + 𝑥 − 1𝑥 − 1
通り
一方、それ以外の場合の列は帰納法の仮定より𝑦 + 𝑥 − 1
𝑥通り なので帰納法より正しい
Parrots
• この証明と同じ手順で符号化・復号ができる
Parrots
• この証明と同じ手順で符号化・復号ができる
Parrots / SaveIt
• Parrots / SaveIt 教訓:
– SaveItみたいに発想力が試されるものもある
–でもParrotsみたいにただ対応させるだけというものもある
Maze
• 畑を切り開いて迷路を作ります
• 幅優先探索したときの深さを大きくしたい
• 切り開ける場所と切り開けない場所があります
• 10問
Maze
• 困難な最適化問題の一般的なテク
Maze
• 困難な最適化問題の一般的なテク
–基本は局所探索
Maze
• 困難な最適化問題の一般的なテク
–基本は局所探索
– ランダム要素を加えて局所探索+繰り返し試行がオススメ
• 実装が簡単
• 時間をかければ多少は改善するようになる
Maze
• 困難な最適化問題の一般的なテク
–基本は局所探索
– ランダム要素を加えて局所探索+繰り返し試行がオススメ
–少し工夫したいならSAっぽいことをやると良い
Maze
• 困難な最適化問題の一般的なテク
–基本は局所探索
– ランダム要素を加えて局所探索+繰り返し試行がオススメ
–職人の技が光るところ
• 近傍の定め方
• 評価関数の定め方
• 焼きなまし等のパラメーター
Maze
• 入力の傾向
Maze
• Field1
–むっちゃ簡単
Maze
• Field2,4
–簡単そう
Maze
• Field2
– これはよく見るとどうやって生成したかわかる
Maze
• Field3,5
–格子が入っている
Maze
• Field3,5
–格子が入っている
– NP困難性の証明に使われた?
Maze
• Field7,8
–小さい
Maze
• Field6,9
–まっしろ
Maze
• FieldA
–おおきい
Maze
• FieldAの特徴: 大域的な探索をうまくする必要があって難しい
–手でやる?
Maze
• FieldAの特徴: 大域的な探索をうまくする必要があって難しい
–手でやる?
–手で大域的な解を作って局所探索をするという手もある
Maze
• FieldAの特徴: 大域的な探索をうまくする必要があって難しい
–手でやる?
–手でやる場合の注意: 斜めに進んだほうが効率的
Disparity
• 有権者の数ができるだけ均等になるように小選挙区を定めて下さい
• 5問
Disparity
• データの傾向
Disparity
• データの傾向
– 01,03,05
Disparity
• データの傾向
– 04
Disparity
• データの傾向
– 04
Disparity
• データの傾向
– 02
Disparity
• 近傍の定め方
• 以下の近傍はどうか?
Disparity
• 近傍の定め方
• 以下の近傍はどうか?
• あんまり良くない(幅が大きすぎて微調整がきかない)
Disparity
• 近傍を次のようにとる
境界10個くらいを抽出 一番良い境界を探す
Disparity
• 評価関数の定め方:disparityそのものを評価関数とする?
Disparity
• 評価関数の定め方:disparityそのものを評価関数とする?
–最大の地域・最小の地域を動かさないと評価に反映されない
Disparity
• 評価関数の定め方:disparityそのものを評価関数とする?
–最大の地域・最小の地域を動かさないと評価に反映されない
–例えば:分散を使うと勾配がきれいにつく
まとめ
• これをやれば良いという定石はあんまないっぽい
まとめ
• これをやれば良いという定石はあんまないっぽい
• せっかくなので楽しんで