JOI2015-2016 春合宿 day 2 Sandwich 解説

65bd3434deeeb8afc00485cdfc3e260a?s=47 snuke
March 21, 2016

JOI2015-2016 春合宿 day 2 Sandwich 解説

おからは栄養"満点"らしいです。

65bd3434deeeb8afc00485cdfc3e260a?s=128

snuke

March 21, 2016
Tweet

Transcript

  1. サンドイッチ  (Sandwich) 解説 JOI  2016  春合宿  day2 snuke

  2. 問題概要 •  R⾏行行C列列のマス⽬目にサンドイッチが並んでいる •  斜辺または他の⼆二辺が空いてるサンドイッチは取れる •  各マスについて、そのマスのサンドイッチを両⽅方取るた めに取る必要のあるサンドイッチの個数の最⼩小値は?

  3. 問題概要 •  R⾏行行C列列のマス⽬目にサンドイッチが並んでいる •  斜辺または他の⼆二辺が空いてるサンドイッチは取れる •  各マスについて、そのマスのサンドイッチを両⽅方取るた めに取る必要のあるサンドイッチの個数の最⼩小値は?

  4. 問題概要 •  R⾏行行C列列のマス⽬目にサンドイッチが並んでいる •  斜辺または他の⼆二辺が空いてるサンドイッチは取れる •  各マスについて、そのマスのサンドイッチを両⽅方取るた めに取る必要のあるサンドイッチの個数の最⼩小値は?

  5. 問題概要 •  R⾏行行C列列のマス⽬目にサンドイッチが並んでいる •  斜辺または他の⼆二辺が空いてるサンドイッチは取れる •  各マスについて、そのマスのサンドイッチを両⽅方取るた めに取る必要のあるサンドイッチの個数の最⼩小値は?

  6. 問題概要 •  R⾏行行C列列のマス⽬目にサンドイッチが並んでいる •  斜辺または他の⼆二辺が空いてるサンドイッチは取れる •  各マスについて、そのマスのサンドイッチを両⽅方取るた めに取る必要のあるサンドイッチの個数の最⼩小値は?

  7. 問題概要 •  R⾏行行C列列のマス⽬目にサンドイッチが並んでいる •  斜辺または他の⼆二辺が空いてるサンドイッチは取れる •  各マスについて、そのマスのサンドイッチを両⽅方取るた めに取る必要のあるサンドイッチの個数の最⼩小値は?

  8. 問題概要 •  R⾏行行C列列のマス⽬目にサンドイッチが並んでいる •  斜辺または他の⼆二辺が空いてるサンドイッチは取れる •  各マスについて、そのマスのサンドイッチを両⽅方取るた めに取る必要のあるサンドイッチの個数の最⼩小値は?

  9. 問題概要 •  R⾏行行C列列のマス⽬目にサンドイッチが並んでいる •  斜辺または他の⼆二辺が空いてるサンドイッチは取れる •  各マスについて、そのマスのサンドイッチを両⽅方取るた めに取る必要のあるサンドイッチの個数の最⼩小値は?

  10. 問題概要 •  R⾏行行C列列のマス⽬目にサンドイッチが並んでいる •  斜辺または他の⼆二辺が空いてるサンドイッチは取れる •  各マスについて、そのマスのサンドイッチを両⽅方取るた めに取る必要のあるサンドイッチの個数の最⼩小値は?

  11. 問題概要 •  R⾏行行C列列のマス⽬目にサンドイッチが並んでいる •  斜辺または他の⼆二辺が空いてるサンドイッチは取れる •  各マスについて、そのマスのサンドイッチを両⽅方取るた めに取る必要のあるサンドイッチの個数の最⼩小値は?

  12. ⼩小課題  1  (35点) •  ⽬目的の2個のサンドイッチの取り⽅方は2通りある (A)  上側のサンドイッチを先にとって下側を次に取る (B)  下側のサンドイッチを先にとって上側を次に取る • 

    (A)についての最⼩小値が求められれば、(B)についても同 様な⽅方法で求めることができるので、(A)のみを考える 先 後
  13. ⼩小課題  1  (35点) •  上側のサンドイッチを取るためには、⾚赤マルの位置のサ ンドイッチを先に取らなければならない •  このように「Xを取るためには先にYを取らなければい けない」という状況を、「XがYに依存している」と呼 ぶことにする

    先 後
  14. ⼩小課題  1  (35点) •  XがYに依存しているとき、X→Yという辺を貼ってみる •  辺が貼られたものを逆順に、取れるものから取っていけ ば緑のサンドイッチを取ることができる

  15. ⼩小課題  1  (35点) •  このようにサイクルができる場合は取ることが出来ない

  16. ⼩小課題  1  (35点) •  各マスについて、(A),(B)パターンを試す –  依存関係を列列挙していき、辺を貼る –  辺が貼られたサンドイッチの個数を求める – 

    ただし、サイクルが存在する場合は取れないと判定する •  計算量量:O((RC)^2)
  17. ⼩小課題  1  (35点) •  具体的にどう計算するか –  単にbool  visited[MAX_̲V]のような配列列で状態を管理理している と、「サイクル」なのか「単に2回訪れただけ」なのかが判定 できない

  18. ⼩小課題  1  (35点) •  具体的にどう計算するか –  DFSを⽤用いると簡潔に実装できる int  state[MAX_V];  //

     0  で初期化   int  dfs(int  v)  {      if  (state[v]  ==  1)  return  INF;      if  (state[v]  ==  2)  return  0;      state[v]  =  1;      int  sum  =  1;      for  (int  u  :  to[v])  {          int  res  =  dfs(u);          if  (res  ==  INF)  return  INF;          sum  +=  res;      }      state[v]  =  2;      return  sum;   }
  19. 実装の簡略略化 •  サンドイッチが三⾓角形なのは扱いにくいので、マス単位 で考えることにする

  20. 実装の簡略略化 •  サンドイッチが三⾓角形なのは扱いにくいので、マス単位 で考えることにする

  21. 実装の簡略略化 •  マス⽬目の隣隣接関係を扱うときのテクニック –  dx[]  =  {-‐‑‒1,  0,  1,  0},

     dy[]  =  {0,-‐‑‒1,0,1} –  for(v=0~∼3)  nx  =  x+dx[v],  ny  =  y+dy[v] •  v  という⽅方向でʻ‘Zʼ’のマスに⼊入ってきた時、そのマスから 貼る辺は  v  と  v  xor  1  の⽅方向のマス –  ʻ‘Nʼ’のマスなら  v  と  v  xor  3 0 2 1 3
  22. ⼩小課題  2  (満点) •  列列ごとに考える •  列列の上から順に依存関係を計算していく

  23. ⼩小課題  2  (満点) •  列列ごとに考える •  列列の上から順に依存関係を計算していく

  24. ⼩小課題  2  (満点) •  列列ごとに考える •  列列の上から順に依存関係を計算していく

  25. ⼩小課題  2  (満点) •  列列ごとに考える •  列列の上から順に依存関係を計算していく •  依存関係の辺は単調増加!

  26. ⼩小課題  2  (満点) •  列列ごとに考える •  列列の上から順に依存関係を計算していく •  依存関係の辺は単調増加! – 

    上側のサンドイッチは必ず上⽅方向に依存しており、 上⽅方向に依存されたマスは上⽅方向に依存しているため
  27. ⼩小課題  2  (満点) •  列列ごとに、上から順に依存関係を計算する •  同じ列列内では依存関係を初期化をせずに計算していく •  依存関係の個数は⾼高々O(RC)なので、列列ごとにO(RC)で 計算でき、全体でO(RC*C)となる

  28. ⼩小課題  2  (満点) •  列列ごとに、上から順に依存関係を計算する •  同じ列列内では依存関係を初期化をせずに計算していく •  依存関係の個数は⾼高々O(RC)なので、列列ごとにO(RC)で 計算でき、全体でO(RC*C)となる

  29. 統計 0 35 100 15 4 1

  30. 統計 0 35 100 菩提樹の⽊木の下で悟りを開くブッダのイラスト 15 4 1 巫⼥女女さんのイラスト おからのイラスト