Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

最小カットを使って「燃やす埋める問題」を解く

13,109 views

Published on

最小カットを使って「燃やす埋める問題」を解く方法について、問題とソースコードつきで、まとめました。ニコニコ生放送「TopCoderでプログラムしてみた」2000回記念放送の資料です。

Published in: Education

最小カットを使って「燃やす埋める問題」を解く

  1. 1. 診断人(@nico_shindannin) 1
  2. 2. 1. 燃やす埋める問題とは 2. 基本 3. 選択肢をうまく並べる 4. 二部グラフの性質を生かす 5. 複雑な制約条件を入れる 6. 最小カットの復元をする 7. 費用を工夫して割り当てる 2
  3. 3. 2. 燃やす埋める問題 引用:Komakiさんのページ http://topcoder.g.hatena.ne.jp/CKomaki/20121019/1350663591 3. FoxAndGo3 引用:TopCoder - SRM594 Div1 Medium http://community.topcoder.com/stat?c=problem_statement&pm=12808&rd=15706 4. The Year of Code Jam 引用:Google Code Jam World Finals 2008 E (プログラミングコンテストチャレンジブック P357) https://code.google.com/codejam/contest/32011/dashboard#s=p4 5. Surrounding Game 引用:TopCoder - SRM558 Div1 Hard https://code.google.com/codejam/contest/32011/dashboard#s=p4 6. 1 引用: 立命館合宿2013 Day2 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2496 7. RabbitWorking 引用: TopCoder - SRM 542 Div1 Hard http://community.topcoder.com/stat?c=problem_statement&pm=11054&rd=14734 3
  4. 4. 4
  5. 5. 燃やす埋める問題 引用:Komakiさんのページ http://topcoder.g.hatena.ne.jp/CKomaki/20121019/1350663591 A,B,Cは「燃やす」か「土に埋める」必要がある。 ◦A,B,Cは「燃やす」とそれぞれ50,60,130円もらえる。 ◦A,B,Cは「土に埋める」と100円もらえる。 ◦BとCの片方だけ「燃やす」と死ぬ。 死なずに最高で何円もらえるか? 5
  6. 6. 複数の小問題がある ◦それぞれの小問題に対し選択肢がある ◦選択肢ごとに、費用・利益がある 選択肢同士に依存関係もありうる ◦小問題1で選択肢Aを選んだら、小問題3でAは選べない。 ◦小問題1も小問題2でも選択肢Aを選んだ時は罰金として 費用がかかる。 全体の費用を最小化(利益を最大化)する 6
  7. 7. 複数の小問題(20問以下) がある。 ◦それぞれの小問題に対し選択肢(Selection)がある ◦選択肢ごとに、費用・利益がある 選択肢同士に依存関係もありうる ◦小問題1で選択肢Aを選んだら、小問題3でAは選べない。 ◦小問題1も小問題2でも選択肢Aを選んだ時は罰金として 費用がかかる。 全体の費用を最小化(利益を最大化)する これなら総当たりで解けます 計算量は20*220 しかし、問題が増えるとO(n*2n)なので解けない。 7
  8. 8. 複数の小問題がある。 ◦それぞれの小問題に対し選択肢がある ◦選択肢ごとに、費用・利益がある 選択肢同士に依存関係もありうる ◦小問題1で選択肢Aを選んだら、小問題3でAは選べない。 ◦小問題1も小問題2でも選択肢Aを選んだ時は罰金として 費用がかかる。 全体の費用を最小化(利益を最大化)する これなら、小問題ごとに独立しているので それぞれの小問題の費用を最小化して足せばいい。 しかし、依存関係があると全体の費用を最小化 できない 8
  9. 9. 複数の小問題(10000問とか)がある ◦それぞれの小問題に対し選択肢がある ◦選択肢ごとに、費用・利益がある 選択肢同士に依存関係もありうる ◦小問題1で選択肢Aを選んだら、小問題3でAは選べない。 ◦小問題1も小問題2でも選択肢Aを選んだ時は罰金として 費用がかかる。 全体の費用を最小化(利益を最大化)する これを最小カットで解きます。 9
  10. 10. 10
  11. 11. 11 燃やす埋める問題 Super Easy A,B,Cは「燃やす」か「土に埋める」必要がある。 ◦A,B,Cは「燃やす」とそれぞれ50,60,130円かかる。 ◦A,B,Cは「土に埋める」と100円かかる。 最小で何円かかるか?
  12. 12. 燃やす埋める問題 Super Easy A,B,Cは「燃やす」か「土に埋める」必要がある。 ◦A,B,Cは「燃やす」とそれぞれ50,60,130円かかる。 ◦A,B,Cは「土に埋める」と100円かかる。 最小で何円かかるか? 12 それぞれ、金額の安い選択肢を選べばよい。 ◦Aを「燃やす」Bを「燃やす」Cを「土に埋める」 ◦50+60+100=210円が最小
  13. 13. 13 s A B t C 50 60 130 100 100 100 燃やす 燃やす 燃やす 土に埋める 土に埋める 土に埋める 頂点sから頂点tへ辺をつなげる。 ◦小問題ごとに並列につなげる ◦選択肢は直列につなげる
  14. 14. 14 s A B t C 50 60 130 100 100 100 燃やす 燃やす 燃やす 土に埋める 土に埋める 土に埋める 最小s-tカットは、このようになる。 ◦最小で50+60+100=210でs→tがつながらなくなる。 ◦カット(赤い線)した部分が、小問題の選択肢になる。
  15. 15. 15 s A B t C 50 60 130 100 100 100 燃やす 燃やす 燃やす 土に埋める 土に埋める 土に埋める 最小s-tカットは、このようになる。 ◦最小で50+60+100=210でs→tがつながらなくなる。 ◦カットした部分が、小問題の選択肢になる。
  16. 16. s-tカットなので、t->sは無視してよい 有向グラフです 切るところは、平面図的につながってなくてよい s側とt側の2つに切る。3つ切ってはいけない。 元のグラフはs->tへの経路が存在する必要がある 16
  17. 17. 最小カットをプログラムで計算するのは困難 最小s-tカット=最大s-tフロー ◦最小カットの各辺のコストが、最大フローの容量になる 最大フローを求めるのにはDinic法を使う O(EV2)だが、実際はもっと速いので、おすすめ 17 s A B t C 50/50 60/60 100/130 50/100 60/100 100/100 流量/容量
  18. 18. http://ideone.com/rwECrx グラフを構築する部分はmain関数にあります。 コードの最後の方をみてください。 頂点0,1,2が頂点A,B,Cに対応しています。 18
  19. 19. 19 燃やす埋める問題 Very Easy A,B,Cは「燃やす」か「土に埋める」必要がある。 ◦A,B,Cは「燃やす」とそれぞれ50,60,130円もらえる。 ◦A,B,Cは「土に埋める」と100円もらえる。 最大で何円もらえるか?
  20. 20. 20 燃やす埋める問題 Very Easy A,B,Cは「燃やす」か「土に埋める」必要がある。 ◦A,B,Cは「燃やす」とそれぞれ50,60,130円もらえる。 ◦A,B,Cは「土に埋める」と100円もらえる。 最大で何円もらえるか? 最小カットは、最小値を求める。最大値ではない。 そこで、最小値を求める問題に置き換える!
  21. 21. 21 燃やす 土に埋める A 50円の利益 100円の利益 B 60円の利益 100円の利益 C 130円の利益 100円の利益 無条件で得られる利益 燃やす 土に埋める A 100円の利益 50円の損失 0円の損失 B 100円の利益 40円の損失 0円の損失 C 130円の利益 0円の損失 30円の損失 利益が大きい選択肢の利益を、無条件で得られるこ とにする→その分選択肢からひくと全て損失に
  22. 22. 22 燃やす 土に埋める A 50円の利益 100円の利益 B 60円の利益 100円の利益 C 130円の利益 100円の利益 これはダメ! ◦負辺があるときの最小カット問題はNP困難 燃やす 土に埋める A -50円の損失 -100円の損失 B -60円の損失 -100円の損失 C -130円の損失 -100円の損失
  23. 23. s A B t C 50 40 0 0 0 30 燃やす 燃やす 燃やす 土に埋める 土に埋める 土に埋める 最小s-tカットは0+0+0=0 あらかじめ貰える利益は100+100+130=330 求める最大値は330-0=330
  24. 24. s A B t C 50 40 0 0 0 30 燃やす 燃やす 燃やす 土に埋める 土に埋める 土に埋める コスト0の辺もグラフに書きましょう! ◦最小カット問題のグラフでは、 辺が元からないのと、損失0の辺とでは、別物です。 ◦最大フローを求めるときに、容量0になるのでいらない辺に なりますが、それでも書きましょう ◦複雑な問題だと、辺が元からないのか、辺があるけどコスト が0なのかで、混乱しやすくなる。
  25. 25. http://ideone.com/WgGXlL 25
  26. 26. 26 燃やす埋める問題 Easy A,Bは「燃やす」か「土に埋める」必要がある。 ◦A,Bは「燃やす」とそれぞれ20,100円かかる。 ◦A,Bは「土に埋める」とそれぞれ50,20円かかる。 ◦Aを燃やしたときに、Bを土に埋めると罰金300円かかる。 最小で何円かかるか?
  27. 27. 27 s A B t 20 100 50 20 燃やす 燃やす 土に埋める 土に埋める Aを燃やしたときにBを土に埋めると 罰金300円かかる
  28. 28. 28 s A B t 20 100 50 20 燃やす 燃やす 土に埋める 土に埋める Aを燃やしたときにBを土に埋めると 罰金300円かかる Aを燃やしたときにBを土に埋めたら まだs-tカットが成立しないようにする
  29. 29. 29 s A B t 20 100 50 20 燃やす 燃やす 土に埋める 土に埋める Aを燃やしたときにBを土に埋めると 罰金300円かかる Aを燃やしたときにBを土に埋めたら まだs-tカットが成立しないようにする 300 罰金
  30. 30. 30 s A B t 20 100 50 20 燃やす 燃やす 土に埋める 土に埋める こうすると、s-tカットするにはB→Aの辺をカッ トせざるをえない。つまり300円かかる。 もちろん、これは最小カットではない。 この制約条件の追加方法を理解できないと その後すべて理解できなくなるので注意! 300 罰金
  31. 31. 31 s A B t 20 100 50 20 燃やす 燃やす 土に埋める 土に埋める 両方を土に埋めると最小カット70円になります。 300 罰金
  32. 32. http://ideone.com/OlgYjD 32
  33. 33. 1.小問題を並列に、選択肢を直列に並べて、グラ フを作る。 2.最大化する問題は、考えうる最大の利益をあら かじめ得てることにして、最小化問題に置き換 える。 3.制約条件を入れるときは、ある選択肢の組み合 わせを選んだ時に、そのままではs-tカットがで きないように、辺を追加する。 33
  34. 34. 34
  35. 35. 35 s A B t C 50 60 130 100 100 100 燃やす 燃やす 燃やす 土に埋める 土に埋める 土に埋める 選択肢はどういう順番に置いてもよい。 ◦ただ、順番が悪いと、制約条件を追加できないことが ある。 考えて選択肢の順番を決めないといけない。
  36. 36. 36 FoxAndGo3 引用:TopCoder - SRM594 Div1 Medium http://community.topcoder.com/stat?c=problem_statement&pm=12808&rd=15706 囲碁っぽい問題。自分が黒番で好きなだけ黒石を 置ける。(死ぬ場所にも置けるので注意) 黒石で白石のまわりを隙間なく囲めば白石を除い て領地(=空きマス)にすることができる。 領地の最大値を求めよ。 盤面の数は最大で50*50。また、白石同士は隣接 していない。
  37. 37. 37 そのまま置かなければ、領地は24 ◦本物の囲碁と違います
  38. 38. 38 黒石を置けば、白石がとれるけど、置いた分だけ 領地が21に減る。何もおかないほうが領地が24 で最大。
  39. 39. 39 このままでは領地は1
  40. 40. 40 黒石を真ん中に置くと、すべての白石が死に、自 分の領地になる。領地は4、これが最大値。
  41. 41. 41 初期の領地は10ですが、黒をうまく置くと、 最大領地は12になるようです。
  42. 42. 42 最大値を求める問題なので、このままでは 最小カットが使えない。 ◦黒石が最初からおいてあるところは絶対領地にできない ◦つまり、仮の最大領地数=盤面の全マスー黒石数 ◦そこから逆に以下のように考える 白石がとれなかったら、領地1の損失 領地(空きマス)で黒石をおいたら、領地1の損失 ◦仮の最大領地数ー最小の領地損失=最大の領地数で求め ることができる。
  43. 43. 43 s t 1 0 1 0 1 0 黒置く 白死領地 黒置く 領地 白のまま 黒石は無視してよい。選択肢がないから。 領地を1の損失と考えたこのグラフは正しい。 「白死領地にするには、まわりに黒を置かない といけない」の制約をどうするか? 領地 白石と隣接する領地 (空きマス) 白石
  44. 44. s t 1 0 1 0 1 0 黒置く 白死領地 黒置く 領地 白のまま 領地 この2つを強制的に切らせたい
  45. 45. s t 1 0 1 0 1 0 黒置く 白死領地 黒置く 領地 白のまま 領地 +∞ +∞
  46. 46. s t 1 0 1 0 1 0 黒置く 白死領地 黒置く 領地 白のまま 領地 +∞ +∞ +∞の制約条件を入れても、最小カットが成立 してしまう。「黒置く」のところを強制的に カットさせたいのにできない。 +∞のリンクを逆にしても、同じ。
  47. 47. 47 s t 0 0 0 1 1 1 領地 白死領地 領地 黒置く 白のまま 「黒置く」と「領地」の選択肢の順番を変える 黒置く
  48. 48. 48 s t 0 0 0 1 1 1 領地 白死領地 領地 黒置く 白のまま +∞の辺を白から領地の方向へ足す 黒置く +∞ +∞
  49. 49. 49 s t 0 0 0 1 1 1 領地 白死領地 領地 黒置く 白のまま 黒置く +∞ +∞ こうすると、領地の辺をカットしても、 まだs-tは繋がっている。最小s-tカットになってい ないので、解にならない。 ◦つまり、元からの領地の部分に黒石をおかないのであれば、 白石を殺して領地にすることはできないという意味。
  50. 50. 50 s t 0 0 0 1 1 1 領地 白死領地 領地 黒置く 白のまま 黒置く +∞ +∞ 仮に隣接する1カ所をカットしても まだs-tは繋がっている
  51. 51. 51 s t 0 0 0 1 1 1 領地 白死領地 領地 黒置く 白のまま 黒置く +∞ +∞ つまり、隣接する領地は、すべて「黒置く」を選ば ないと、s-tカットできない。 「白石を殺して領地にするには、まわりに黒を置か ないといけない」という制約通りになってる。
  52. 52. 52 s t 0 0 0 1 1 1 領地 白死領地 領地 黒置く 白のまま 黒置く +∞ +∞ うっかり+∞の辺を領地から隣接する白方向に 足すと、うまくいかない。 上の例で、「黒置く」をカットしなくても、s-t カットができている。
  53. 53. 53 s t 0 0 0 1 1 1 領地 白死領地 領地 黒置く 白のまま 黒置く +∞ +∞ うっかり+∞の辺を領地から隣接する白方向に 足すと、うまくいかない。 上の例で、「黒置く」をカットしなくても、s-t カットができている。
  54. 54. 54 FoxAndGo3 引用:TopCoder SRM594 Div1 Medium http://community.topcoder.com/stat?c=problem_statement&pm=12808&rd=15706 囲碁っぽい問題。自分が黒番で好きなだけ黒石を 置ける。(死ぬ場所にも置けるので注意) 黒石で白石のまわりを隙間なく囲めば白石を除い て領地(=空きマス)にすることができる。 領地の最大値を求めよ。 盤面の数は最大で50*50。また、白石同士は隣接 していない。←この条件があると、囲む判定を工 夫する必要がありますが、それでも解けます。
  55. 55. 55
  56. 56. 56 The Year of Code Jam 引用:Google Code Jam World Finals 2008 E (プログラミングコンテストチャレンジブック P357) https://code.google.com/codejam/contest/32011/dashboard#s=p4 カレンダーN月で、各月はM日。 ◦白:コンテストが開かれない日 ◦青:コンテストに参加する日 ◦?:コンテストが開かれるが、参加しようか迷っている日 1つのコンテストに参加すると ◦幸福度の初期値は4 ◦カレンダー上で隣接する日に参加するコンテスト1つにつき幸 福度は1下がる 幸福度の最大値を求めなさい。 1≦N≦50, 1≦M≦50
  57. 57. 57 青が4点。青同士が隣合うと-1点。 最高点がとれるように?の色を青か白にせよ。
  58. 58. 58 最大値問題から最小値問題への置き換えをする。 ◦?のマスは元から4点取ってることにする。 ◦?を白にしたら、4点減点。 s t 4 0 白にする 青にする ?
  59. 59. 59 ?と隣接する青マスに対して、 ◦?が青になったときは、1点減点 ◦?が白になったときは、何もしない s t 4 0 白にする 青にする ?
  60. 60. 60 sから青マスへ+∞の辺をつなげる。 ◦+∞の辺を、s,tのどちら側につなげても良いが、制約条 件を考えること。 今回のようにsと青マスをつないだ場合は、青マ スから?へコスト2を足すとよい。 ◦青マス、?マスの両方でコスト1ずつ損するので、コス ト2になる。 s t 4 0 白にする 青にする ? +∞ 2
  61. 61. 61 ?-?間の制約条件 s t 4 0 白にする 青にする ? ? 青にする 0 白にする 4
  62. 62. 62 ?を両方青にしても、s-tカットできる。 ◦コスト2を課すことができない。 s t 4 0 白にする 青にする ? ? 青にする 0 白にする 4 2
  63. 63. 63 逆向きにしても、s-tカットできるのでダメ。 s t 4 0 白にする 青にする ? ? 青にする 0 白にする 4 2
  64. 64. 64 両向きにしても、s-tカットできるのでダメ。 s t 4 0 白にする 青にする ? ? 青にする 0 白にする 4 2
  65. 65. 65 グリッドグラフは二部グラフである。 ◦EVEN同士とODD同士がつながることはない。 マスをEVENとODDで区別すれば、先ほどの問題 は解決できる EVEN:(x+y)%2==0 ODD:(x+y)%2==1
  66. 66. 66 ◦ODDのマスに対して、3章で学んだ、選択肢を並べ替え るテクニックを使う ◦このようにすると、両方とも青にするをカットしても、 s-tカットにならない。コスト2の辺もカットする必要が ある。 s t 4 4 白にする 青にする ? ? 白にする 0 EVEN ODD 0 青にする 2
  67. 67. 67 s t 4 4 白にする 青にする ? ? 白にする 0 EVEN ODD 0 青にする 2 +∞ 2 ODD EVEN 2 +∞ ◦ODD側の青マスからt側に+∞の辺を足す。 これでグラフが完成です。
  68. 68. http://ideone.com/wsv2RY プログラミングコンテストチャレンジブックでは 白マスもでてきますが、必要ありません。 68
  69. 69. 69
  70. 70. 70 Surrounding Game 引用:TopCoder - SRM558 Div1 Hard https://code.google.com/codejam/contest/32011/dashboard#s=p4 長方形の盤面(最大20マス*20マス)があり、す べてのマスに利益biと費用ciが割り当てられてい る。 ◦マスに石を置くか、全ての隣接するマスに石を置くと、 利益biが得られる。 ◦マスに石を置くと、費用ciがかかる スコア=全利益-全費用とする。スコアを最大化 せよ。
  71. 71. 71 b0=3 c0=8 b1=7 c1=1 b2=4 c2=9 b3=5 c3=1 b4=7 c4=6 b5=9 c5=5 b6=5 c6=3 b7=7 c7=2 b8=1 c8=0
  72. 72. 72 b0=3 c0=8 b1=7 c1=1 b2=4 c2=9 b3=5 c3=1 b4=7 c4=6 b5=9 c5=5 b6=5 c6=3 b7=7 c7=2 b8=1 c8=0 置いた場所の利益b1=7、置く損失c1=1 ◦つまり、スコアは、7-1=6
  73. 73. 73 b0=3 c0=8 b1=7 c1=1 b2=4 c2=9 b3=5 c3=1 b4=7 c4=6 b5=9 c5=5 b6=5 c6=3 b7=7 c7=2 b8=1 c8=0 b4のように囲んだ場所の利益も得られる。 ◦スコアは、b1-c1+b3-c3+b5-c5+b7-c7+b4=26
  74. 74. 74 b0=3 c0=8 b1=7 c1=1 b2=4 c2=9 b3=5 c3=1 b4=7 c4=6 b5=9 c5=5 b6=5 c6=3 b7=7 c7=2 b8=1 c8=0 囲むか置くかで点が得られる。b4のように囲んだ場所 に置いても、利益が2倍得られたりしないので注意! スコアは、b1-c1+b3-c3+b5-c5+b7-c7+b4-c4=20
  75. 75. 制約条件が難しいので、まずは、1マスだけ考え る ◦マスに石を置くか、全ての隣接するマスに石を置くと、 利益が得られる。→ OR の条件がやっかい ◦マスに石を置くと、費用がかかる。 75
  76. 76. 76 まず、選択肢として、置く・置かないはある 最小値問題にする ◦bi-ci>0のとき、元からbi-ciのもらえてるとすれば、置い たときはコスト0、置かないときはbi-ci s t 置く 0 置かない bi-ci
  77. 77. 77 まず、選択肢として、置く・置かないはある 最小値問題にする ◦bi-ci<0のとき、損失するか0のままなので、置いたとき はコストci-bi、置かないときは0 s t 置く ci-bi 置かない 0
  78. 78. 78 ここから先はbi-ci>0ときだけのグラフを書きます。 ◦bi-ci>0でもci-bi>0でも、グラフの形はかわらず、コス トが違うだけ。あまり影響はない。
  79. 79. 79 他に、囲まれる・囲まれないという状態もある。 1つのマスごとに、2つの頂点を使えば、良いのでは ないか? 囲む・囲まれないは、元からbiもらえてることにする。 これでいいの? s 置 く t 置く 置かない 0 囲 む 囲まれない bi 囲まれる 0 bi-ci
  80. 80. 80 これはダメ。 「置く」かつ「囲まれる」でs-tカットできる ◦「置く」かつ「囲まれる」で利益の2重どり(2bi-ci)に なってしまう。 s 置 く t 置く 置かない bi-ci 0 囲 む 囲まれない bi 囲まれる 0
  81. 81. 81 「囲む」から「置く」へコスト+∞の辺を追加 「置く」かつ「囲まれる」は許されなくなる。 ◦もとから無意味な状態(「囲まれる」場所に「置く」メ リット)はないので、強制的に除外しても構わない。 s 置 く t 置く 置かない bi-ci 0 囲 む 囲まれない bi 囲まれる 0 +∞
  82. 82. 82 s 置 く t 置く 置かない bi-ci 0 囲 む 囲まれない bi 囲まれる 0 +∞ EVEN (偶数マス) ODD (奇数マス) 置 く 置く 置かない bi-ci 0 囲 む 囲まれない bi 囲まれる 0 +∞ 「囲まれるには、周り全てに置く必要がある」 の制約条件を入れる準備として、奇数ODDマスの選択 肢をすべて逆にする。
  83. 83. 83 s 置 く t 置く 置かない bi-ci 0 囲 む 囲まれない bi 囲まれる 0 +∞ 置 く 置く 置かない bi-ci 0 囲 む 囲まれない bi 囲まれる 0 +∞ EVEN (偶数マス) ODD (奇数マス) 「囲まれる」とき「隣に置かない」のは禁止なので これらを選んだ時にs-tカットができないように+∞ の辺を貼ればよい。 +∞ +∞
  84. 84. http://ideone.com/9kZXjO 84
  85. 85. 85
  86. 86. 86 1 引用: 立命館合宿2013 Day2 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2496 長さnのビット列がある. ◦左からi番目のビットが1のとき,スコアをai点得られる. ◦左からi番目のビットを中心に距離w以内にある1の個数 (=|{j∈{1,…,n}∩{i-w,…,i+w}|左からj番目のビットが1}|) が奇数のとき,スコアをbi点得られる. スコアを最も多く得られるようなビット列を求め よ.
  87. 87. 公式の解説もぜひ参考にしてください。 http://www.slideshare.net/oupc/h1- 17155052 87
  88. 88. 各ビットごとに、2つの得点aiとbiがある。 88 ????????? ai 8 2 3 4 2 4 5 7 1 bi 1 3 9 7 1 5 5 8 6 w=2 ビット列
  89. 89. ビットが1のところは、ai点得られる。 89 110111011 ai 8 2 3 4 2 4 5 7 1 bi 1 3 9 7 1 5 5 8 6 w=2 ビット列
  90. 90. w=2なので、範囲[i-2,i+2]の間のビット1の数 が奇数なら、bi点得られる。 90 110111011 ai 8 2 3 4 2 4 5 7 1 bi 1 3 9 7 1 5 5 8 6 w=2 ビット列 234434432 ビット列[i-2,i+2] 1が3個
  91. 91. この場合、合計点は、 8+2+4+2+4+7+1+3+1+8=40点 最大得点となるときの、ビット列を求める問題 ◦最大得点を求める問題ではない。 91 110111011 ai 8 2 3 4 2 4 5 7 1 bi 1 3 9 7 1 5 5 8 6 w=2 ビット列 234434432 ビット列[i-2,i+2]
  92. 92. これまでの問題のように、グラフをつくれるが… ◦ビット1かビット0かの選択。元からai点もらえること にしておいて、ビット0のときに損失ai点となるように する。 「距離w以内にある1の個数が奇数のときbi点」の 条件の追加が難しい。 ◦グラフで考えたら、「ビット1を選択したカットの数を 数える」という処理が必要になり、たぶん不可能。 92
  93. 93. ビット列の累積和(mod2)を決める問題とみな す。 累積和が分かれば、範囲の和は求められる。 ◦ビットiをk[i]とする。 ◦ビット0~iの累積和をx[i+1]=k[0]+k[1]+…+k[i]とす る。(x[0]=0) ビットiの値 k[i]=x[i+1]-x[i] ビットl~rの総和 k[l]+k[l+1]+...+k[r]=x[r+1]-x[l] ビットi-w~i+wの総和 x[i+w+1]-x[i-w] 93 x[0] x[1] x[2] x[3] +k[0] +k[1] +k[2] 0 k[0] k[0]+k[1] k[0]+k[1]+k[2]
  94. 94. 累積和xを使えば、制約条件も簡単になる。 ◦x[i+w+1]-x[i-w]=1ならbi点 mod2なので、奇数個なら1 ◦x[i+1]-x[i]=1ならai点 2つの項の関係なら、最小カット用のグラフに、 制約条件いれることが簡単にできる。 94
  95. 95. あらかじめai,bi全ての得点をもらえたことにして、 最小化問題に置き換える。 端の処理が難しいので、前後にw個の番兵をいれ る。番兵の部分は範囲外で、ビット1を数えると きに影響を与えないようにしたいので、ビット0 とする。 ◦k={0.....0??.......??0.....0} 95 w個 w個 n個
  96. 96. 累積和xは、先ほどのページのように、x[0]=0の 分、1要素増える。 また、後ろの番兵の処理は、要注意。元のビット の最後の要素が続くことになる。 ◦なぜなら、0を足すかぎり、累積和は変わらないので。 つまり、2パータン試す必要がある。 ◦x={0......0??.......?00.....0} または ◦x={0......0??.......?11.....1} 96 w+1個 w個 n個 w+1個 w個 n個 元のビットの部分だけど(番兵ではない) 値が決まっているのに注意。
  97. 97. 97 次のページからのグラフはn=4、w=1のケースで す。
  98. 98. 98 まず、選択ができるビットについて考える。 ◦x[i+1]-x[i]=1(mod2)で得点ai-wの制約条件を入れたい。 得点aもx[i+1]-x[i]=0のとき減点ai-wの最小化とみなす ◦つまり隣合うx[i+1]とx[i]が同じ値なら、コストai-wをカット させるようにすればいい。→このグラフでは無理! s x[2] t x[3] x[4] x[5] x[1] x[0] x[6] 0にする 0にする 0にする 0にする 1にする 1にする 1にする 1にする 注意:これらの辺は すべてコスト0です。 (狭いので文字は省略)
  99. 99. 99 x[奇数]の選択肢を入れ替えて、制約の双方向リンク を足す。 ◦たとえばx[2],x[3]に着目すると、 x[2]を0にする,x[3]を0にするとき、a1をカットしないといけない。 x[2]を1にする,x[3]を1にするとき、a1をカットしないといけない。 ◦これでコストaiをグラフに追加できた。 s x[2] t x[3] x[4] x[5] x[1] x[0] x[6] 0にする 1にする 0にする 1にする 1にする 0にする 1にする 0にする a3 a2 a1 a0
  100. 100. 100 s x[2] t x[3] x[4] x[5] x[1] x[0] x[6] 0にする 1にする 0にする 1にする 1にする 0にする 1にする 0にする a3 a2 a1 a0 biについても同様。 ◦x[i+w+1]-x[i-w]=1(mod2)で得点bi-wの制約条件を入れたい。 ◦x[i+w+1]-x[i-w]=0のとき減点bi-wの最小化とみなす 奇数個(2*w+1)離れるところの頂点を結ぶので、このグ ラフにうまく足せる。(偶数個ならこの問題は解けな い。) b0 b1 b2 b3
  101. 101. s a0 101 x[2] t x[3] x[4] x[5] x[1] x[0] x[6] 0にする 1にする 0にする 1にする 1にする 0にする 1にする 0にする a3 a2 a1 番兵の部分の辺を考える。 ◦x[0],x[1]は、ビット0固定 ◦右側の番兵・1固定の部分を考える。 b0 b1 b2 b3
  102. 102. 102 0にする、1にするは交互に並べないといけない のは同じ。 s a0 x[2] t x[3] x[4] x[5] x[1] x[0] x[6] 0にする 1にする 0にする 1にする 1にする 0にする 1にする 0にする a3 a2 a1 b0 b1 b2 b3 1にする 0にする 1にする 0にする 0にする 1にする
  103. 103. s 103 a0 x[2] t x[3] x[4] x[5] x[1] x[0] x[6] 0にする 1にする 0にする 1にする 1にする 0にする 1にする 0にする a3 a2 a1 b0 b1 b2 b3 1にする 0にする 1にする 0にする 0にする 1にする 0固定のビット ◦「0にする」をすでに選択した(=カットした)とみな すので、辺は不要。
  104. 104. s 104 0固定のビット ◦「0にする」をすでに選択した(=カットした)とみな すので、辺は不要。「1にする」は、もうカットできな いので、+∞の辺にする。 a0 x[2] t x[3] x[4] x[5] x[1] x[0] x[6] 0にする 1にする 0にする 1にする 1にする 0にする 1にする 0にする a3 a2 a1 b0 b1 b2 b3 1にする 0にする +∞ +∞
  105. 105. 累積和xは、先ほどのページのように、x[0]=0の 分、1要素増える。 また、後ろの番兵の処理は、要注意。元のビット の最後の要素が続くことになる。 ◦なぜなら、0を足すかぎり、累積和は変わらないので。 つまり、2パータン試す必要がある。 ◦x={0......0??.......?00.....0} または ◦x={0......0??.......?11.....1} 105 w+1個 w個 n個 w+1個 w個 n個 元のビットの部分だけど(番兵ではない) 値が決まっているのに注意。
  106. 106. s 106 x[5],x[6]が0固定の場合 ◦「0にする」を選択する(カットする)→「1にする」が +∞の辺 a0 x[2] t x[3] x[4] x[5] x[1] x[0] x[6] 0にする 1にする 0にする 1にする 0にする 1にする a3 a2 a1 b0 b1 b2 b3 +∞ +∞ +∞ +∞
  107. 107. s 107 x[5],x[6]が0固定の場合のグラフの最終形 ◦コスト0の辺は省きました。 a0 x[2] t x[3] x[4] x[5] x[1] x[0] x[6] a3 a2 a1 b0 b1 b2 b3 +∞ +∞ +∞ +∞
  108. 108. s 108 a0 x[2] t x[3] x[4] x[5] x[1] x[0] x[6] 0にする 1にする 0にする 1にする 0にする 1にする a3 a2 a1 b0 b1 b2 b3 +∞ +∞ +∞ +∞ x[5],x[6]が1固定の場合 ◦「1にする」を選択する(カットする)→「0にする」が +∞の辺
  109. 109. s 109 a0 x[2] t x[3] x[4] x[5] x[1] x[0] x[6] a3 a2 a1 b0 b1 b2 b3 +∞ +∞ +∞ +∞ x[5],x[6]が1固定の場合のグラフの最終形 ◦コスト0の辺は省きました。
  110. 110. ノードsから辿れる範囲を求める(これ以上流せ ないところcap=0は、リンクがなくなる) ◦ノードsから幅優先探索すればよい。 流し終わったあと ◦sourceからたどれる範囲が、最小カット時のs側。 ◦たどれないほうがt側。その境界がカットするところ。 復元するときは、 ◦x[奇数]・x[偶数]の0,1が互い違いになってること ◦求めるべきなのはkなので、xの差をとることを忘れない。 110
  111. 111. http://ideone.com/7SiimG 111
  112. 112. 112
  113. 113. 113 RabbitWorking 引用: TopCoder - SRM 542 Div1 Hard http://community.topcoder.com/stat?c=problem_statement&pm=11054&rd=14734 N匹(N≦50)のうさぎの集団がいる。 うさぎの集団から何匹かを選ぶ ◦利益の合計Pは、選んだウサギの集団、すべてのペア利 益pikの総和で求められる(0≦pik≦9) ◦費用Cは、C=K(200-K)で求められる。Kは選んだうさぎ の数 効率P/Cを最大化せよ(効率は実数)
  114. 114. 114 兎0 兎1 兎2 兎0 - 7 1 兎1 7 - 2 兎2 1 2 - 兎 0 兎 1 兎 2 兎 0 兎 2 兎 1 P=7+1+2=10, C=3*(200-3)=591, P/C=10/591 P=1, C=2*(200-2)=396, P/C=1/396 うさぎのペア利益pikの表
  115. 115. 「効率P/Cを最大化せよ(効率は実数)」と割 り算がでてきて、どうにもならない。 115 兎 0 兎 1 兎 2 兎 1 兎 0 兎 2 兎 0 兎 2 兎 1 兎 0 兎 2 兎 1 兎 0 兎 2 兎 1 P/C 0 1/396 2/396 10/591 7/396(求めたいのはこれ)
  116. 116. P/C>a/b(a,bは非負整数)を満たすような最大の a/bを求める二分探索にする ◦P/C>x(xは整数)は不可。P/Cは実数をとりうるので。 ◦P/C>x(xは実数)は可能で二分探索はできるが… 最大流の計算時間・精度が不安。 116 兎 0 兎 1 兎 2 兎 1 兎 0 兎 2 兎 0 兎 2 兎 1 兎 0 兎 2 兎 1 兎 0 兎 2 兎 1 P/C Step 2 a/b もっと下 Step 1 a/b もっと上 Step 3 a/b もっと上 Step 4 a/b もっと上 Step 5 a/b もっと下
  117. 117. 割り算を避けるために、二分探索の形にして、両辺 に分母をかけて、整数問題として扱うというテク ニックは、プログラミングコンテストチャレンジ ブック第2版P132「平均最大化」も参考にしてく ださい。 117
  118. 118. 118 푃 퐶 > 푎 푏 푏푃−푎퐶>0 푏 푝푖푗 퐺 푖<푗 −푎퐾200−퐾>0 P/C>a/bを数式変形すると、以上のようになる。 ◦Kは、選んだウサギの数。 ◦Gはウサギの集合。i<jとなるpijの数は、K(K-1)/2。 ◦最小カットに持ち込むなら、このKの値が、辺のコス トに入らないようにしたい。
  119. 119. 119 s ペア 01 t 雇う 組合わせなし 雇う 雇わない 組み合わせあり 雇わない 兎 0 兎 1 グラフは以上のように なりそう(K=1の場合) 1辺のコストにKを使いたくないので (全コスト)=(辺の数)*(1辺のコスト) の形にして、辺の数側にKを組み込んでしまう。 ウサギペアはK(K-1)/2、ウサギの数はK K(K-1)/2 *(???) +K*(???) の形であれば最小カットに持ち込める。
  120. 120. 以上のように数式変形すると ◦ウサギペア K(K-1)/2箇所の辺に、bpij+2aのコスト i<jを満たすのが、 K(K-1)/2個あるので、これでよい。 ◦ウサギ K箇所の辺に 199aのコスト 左辺の最大値>0となればいいので、左辺を最小 カットする。 120 数式はTopCoder公式解説の ものです.
  121. 121. 121 s ペア 01 t 雇う 199a 組合わせなし bp01+2a 雇う 199a 雇わない 0 組み合わせあり 0 兎 0 兎 1 組み合わせあり・なしについては、組み合わせ ありの利益→組み合わせなしの損失に置き換え。 「組み合わせあり」を選んだときは、「雇う」 を選ばせたいので、制約条件の+∞の辺を追加 する。 雇わない 0 +∞ +∞
  122. 122. long long ◦問題では10-9の精度が求められてるので、a/bのa,bを intにすると精度が足りません。辺のコストにlong longの値がくるので、最大流はlong longに対応させ る必要があります。 分数の扱い ◦bを十分に大きい値(1012とか)にして、aを0~1012 で二分探索すれば大丈夫です 別解 ◦P,Cは取れる値の数は実はあまりないので、P/Cの取れ る値も限られます。 この方法だと精度を心配する必要 はなくなります。 ◦http://apps.topcoder.com/wiki/display/tc/SRM+542の公式解説を参考にしてください. 122
  123. 123. http://ideone.com/8QljRJ 123
  124. 124. 124 終わり ここまで読んでくださり ありがとうございました 質問・提案などありましたら Twitterの@nico_shindanninまでお願いします。
  125. 125. Komakiさんのページ ◦http://topcoder.g.hatena.ne.jp/CKomaki/20121019/1350663591 Komiyaさんのページ ◦http://d.hatena.ne.jp/komiyam/20121208/1354895372 プログラミングコンテストチャレンジブック第2版 TopCoder ◦http://community.topcoder.com/tc 125
  126. 126. Dual Core CPU 引用:POJ No.3469 (プログラミングコンテストチャレンジブック P212) http://poj.org/problem?id=3469 N個のモジュールを、コアAかコアBで実行する。 ◦モジュールiをコアAで実行すると、コストがAiかかる ◦モジュールiをコアBで実行すると、コストがBiかかる M個のモジュールの組(ak,bk)はデータ交換を行う ◦もし、akとbkを異なるコアで実行した場合、wkのコスト がさらにかかる。 コストの和の最小値を求めなさい。 1≦N≦20000, 1≦ M ≦200000 126
  127. 127. 127 「何を選択するか」を取り扱うのに、2つ方法が あるので、悩んだ 1.ノードが、s側に属するか、t側に属するかで、選択肢 を割り振る(たいていの他の資料の方法) 3択以上の選択肢、直列に辺がならぶとき(そういう問題 はでてきてないけど)、分かりづらい? 2.辺に、選択肢を割り当て、辺をカットしたら選択した ということにする(本文の方法) 6章の問題のような、カットする選択肢となる辺のコストが 全て0になるときに、説明が不十分かも→でも、いまから全 部直せない…。 min-cutを定式化すると、 푐푖푗푑푖푗(푖,푗)∈퐸の形なので、辺に選 択肢が直結してたほうが、直感的かもと思った。
  128. 128. 128 数式でアプローチする方法 ◦http://en.wikipedia.org/wiki/Max-flow_min- cut_theorem のMin-Cut(Dual)の式は説明したほうが良かっ たかも。 c : 辺のコスト d : カットした辺→1, カットしてない辺→0 p : s側の頂点→1, t側の頂点→0 注 : 上記の定義は、解のうちの1つです。他の値でも最適解をとり うる場合があります。 ◦この式をちゃんと理解しておけば、数学得意な人に対しては、 いらぬ混乱は減らせるかも。 ◦ただ、この式をちょっと変形するなどして、また別なタイプ の問題を解くというのが見えないので、本文中の説明はやめ ておきました。数式を使ったからこそ見えやすい応用があれ ば、本文中に入れたのですが。 ◦あと、Komiyaさんのページのほうがずっと良いので、自分が 説明しないほうが良い気もしました(泣)

×