Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
最小カットを使って「燃やす埋める問題」を解く | PDF
[go: Go Back, main page]

診断人(@nico_shindannin) 
1
1. 燃やす埋める問題とは 
2. 基本 
3. 選択肢をうまく並べる 
4. 二部グラフの性質を生かす 
5. 複雑な制約条件を入れる 
6. 最小カットの復元をする 
7. 費用を工夫して割り当てる 
2
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
燃やす埋める問題 
引用: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
複数の小問題がある 
◦それぞれの小問題に対し選択肢がある 
◦選択肢ごとに、費用・利益がある 
選択肢同士に依存関係もありうる 
◦小問題1で選択肢Aを選んだら、小問題3でAは選べない。 
◦小問題1も小問題2でも選択肢Aを選んだ時は罰金として 費用がかかる。 
全体の費用を最小化(利益を最大化)する 
6
複数の小問題(20問以下) がある。 
◦それぞれの小問題に対し選択肢(Selection)がある 
◦選択肢ごとに、費用・利益がある 
選択肢同士に依存関係もありうる 
◦小問題1で選択肢Aを選んだら、小問題3でAは選べない。 
◦小問題1も小問題2でも選択肢Aを選んだ時は罰金として 費用がかかる。 
全体の費用を最小化(利益を最大化)する 
これなら総当たりで解けます 
計算量は20*220 
しかし、問題が増えるとO(n*2n)なので解けない。 
7
複数の小問題がある。 
◦それぞれの小問題に対し選択肢がある 
◦選択肢ごとに、費用・利益がある 
選択肢同士に依存関係もありうる 
◦小問題1で選択肢Aを選んだら、小問題3でAは選べない。 
◦小問題1も小問題2でも選択肢Aを選んだ時は罰金として 費用がかかる。 
全体の費用を最小化(利益を最大化)する 
これなら、小問題ごとに独立しているので それぞれの小問題の費用を最小化して足せばいい。 
しかし、依存関係があると全体の費用を最小化 できない 
8
複数の小問題(10000問とか)がある 
◦それぞれの小問題に対し選択肢がある 
◦選択肢ごとに、費用・利益がある 
選択肢同士に依存関係もありうる 
◦小問題1で選択肢Aを選んだら、小問題3でAは選べない。 
◦小問題1も小問題2でも選択肢Aを選んだ時は罰金として 費用がかかる。 
全体の費用を最小化(利益を最大化)する 
これを最小カットで解きます。 
9
10
11 
燃やす埋める問題 Super Easy 
A,B,Cは「燃やす」か「土に埋める」必要がある。 
◦A,B,Cは「燃やす」とそれぞれ50,60,130円かかる。 
◦A,B,Cは「土に埋める」と100円かかる。 
最小で何円かかるか?
燃やす埋める問題 Super Easy 
A,B,Cは「燃やす」か「土に埋める」必要がある。 
◦A,B,Cは「燃やす」とそれぞれ50,60,130円かかる。 
◦A,B,Cは「土に埋める」と100円かかる。 
最小で何円かかるか? 
12 
それぞれ、金額の安い選択肢を選べばよい。 
◦Aを「燃やす」Bを「燃やす」Cを「土に埋める」 
◦50+60+100=210円が最小
13 
s 
A 
B 
t 
C 
50 
60 
130 
100 
100 
100 
燃やす 
燃やす 
燃やす 
土に埋める 
土に埋める 
土に埋める 
頂点sから頂点tへ辺をつなげる。 
◦小問題ごとに並列につなげる 
◦選択肢は直列につなげる
14 
s 
A 
B 
t 
C 
50 
60 
130 
100 
100 
100 
燃やす 
燃やす 
燃やす 
土に埋める 
土に埋める 
土に埋める 
最小s-tカットは、このようになる。 
◦最小で50+60+100=210でs→tがつながらなくなる。 
◦カット(赤い線)した部分が、小問題の選択肢になる。
15 
s 
A 
B 
t 
C 
50 
60 
130 
100 
100 
100 
燃やす 
燃やす 
燃やす 
土に埋める 
土に埋める 
土に埋める 
最小s-tカットは、このようになる。 
◦最小で50+60+100=210でs→tがつながらなくなる。 
◦カットした部分が、小問題の選択肢になる。
s-tカットなので、t->sは無視してよい 
有向グラフです 
切るところは、平面図的につながってなくてよい 
s側とt側の2つに切る。3つ切ってはいけない。 
元のグラフはs->tへの経路が存在する必要がある 
16
最小カットをプログラムで計算するのは困難 
最小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 
流量/容量
http://ideone.com/rwECrx 
グラフを構築する部分はmain関数にあります。 コードの最後の方をみてください。 
頂点0,1,2が頂点A,B,Cに対応しています。 
18
19 
燃やす埋める問題 Very Easy 
A,B,Cは「燃やす」か「土に埋める」必要がある。 
◦A,B,Cは「燃やす」とそれぞれ50,60,130円もらえる。 
◦A,B,Cは「土に埋める」と100円もらえる。 
最大で何円もらえるか?
20 
燃やす埋める問題 Very Easy 
A,B,Cは「燃やす」か「土に埋める」必要がある。 
◦A,B,Cは「燃やす」とそれぞれ50,60,130円もらえる。 
◦A,B,Cは「土に埋める」と100円もらえる。 
最大で何円もらえるか? 
最小カットは、最小値を求める。最大値ではない。 
そこで、最小値を求める問題に置き換える!
21 
燃やす 
土に埋める 
A 
50円の利益 
100円の利益 
B 
60円の利益 
100円の利益 
C 
130円の利益 
100円の利益 
無条件で得られる利益 
燃やす 
土に埋める 
A 
100円の利益 
50円の損失 
0円の損失 
B 
100円の利益 
40円の損失 
0円の損失 
C 
130円の利益 
0円の損失 
30円の損失 
利益が大きい選択肢の利益を、無条件で得られるこ とにする→その分選択肢からひくと全て損失に
22 
燃やす 
土に埋める 
A 
50円の利益 
100円の利益 
B 
60円の利益 
100円の利益 
C 
130円の利益 
100円の利益 
これはダメ! 
◦負辺があるときの最小カット問題はNP困難 
燃やす 
土に埋める 
A 
-50円の損失 
-100円の損失 
B 
-60円の損失 
-100円の損失 
C 
-130円の損失 
-100円の損失
s 
A 
B 
t 
C 
50 
40 
0 
0 
0 
30 
燃やす 
燃やす 
燃やす 
土に埋める 
土に埋める 
土に埋める 
最小s-tカットは0+0+0=0 
あらかじめ貰える利益は100+100+130=330 
求める最大値は330-0=330
s 
A 
B 
t 
C 
50 
40 
0 
0 
0 
30 
燃やす 
燃やす 
燃やす 
土に埋める 
土に埋める 
土に埋める 
コスト0の辺もグラフに書きましょう! 
◦最小カット問題のグラフでは、 辺が元からないのと、損失0の辺とでは、別物です。 
◦最大フローを求めるときに、容量0になるのでいらない辺に なりますが、それでも書きましょう 
◦複雑な問題だと、辺が元からないのか、辺があるけどコスト が0なのかで、混乱しやすくなる。
http://ideone.com/WgGXlL 
25
26 
燃やす埋める問題 Easy 
A,Bは「燃やす」か「土に埋める」必要がある。 
◦A,Bは「燃やす」とそれぞれ20,100円かかる。 
◦A,Bは「土に埋める」とそれぞれ50,20円かかる。 
◦Aを燃やしたときに、Bを土に埋めると罰金300円かかる。 
最小で何円かかるか?
27 
s 
A 
B 
t 
20 
100 
50 
20 
燃やす 
燃やす 
土に埋める 
土に埋める 
Aを燃やしたときにBを土に埋めると 罰金300円かかる
28 
s 
A 
B 
t 
20 
100 
50 
20 
燃やす 
燃やす 
土に埋める 
土に埋める 
Aを燃やしたときにBを土に埋めると 罰金300円かかる 
Aを燃やしたときにBを土に埋めたら まだs-tカットが成立しないようにする
29 
s 
A 
B 
t 
20 
100 
50 
20 
燃やす 
燃やす 
土に埋める 
土に埋める 
Aを燃やしたときにBを土に埋めると 罰金300円かかる 
Aを燃やしたときにBを土に埋めたら まだs-tカットが成立しないようにする 
300 
罰金
30 
s 
A 
B 
t 
20 
100 
50 
20 
燃やす 
燃やす 
土に埋める 
土に埋める 
こうすると、s-tカットするにはB→Aの辺をカッ トせざるをえない。つまり300円かかる。 
もちろん、これは最小カットではない。 
この制約条件の追加方法を理解できないと その後すべて理解できなくなるので注意! 
300 
罰金
31 
s 
A 
B 
t 
20 
100 
50 
20 
燃やす 
燃やす 
土に埋める 
土に埋める 
両方を土に埋めると最小カット70円になります。 
300 
罰金
http://ideone.com/OlgYjD 
32
1.小問題を並列に、選択肢を直列に並べて、グラ フを作る。 
2.最大化する問題は、考えうる最大の利益をあら かじめ得てることにして、最小化問題に置き換 える。 
3.制約条件を入れるときは、ある選択肢の組み合 わせを選んだ時に、そのままではs-tカットがで きないように、辺を追加する。 
33
34
35 
s 
A 
B 
t 
C 
50 
60 
130 
100 
100 
100 
燃やす 
燃やす 
燃やす 
土に埋める 
土に埋める 
土に埋める 
選択肢はどういう順番に置いてもよい。 
◦ただ、順番が悪いと、制約条件を追加できないことが ある。 
考えて選択肢の順番を決めないといけない。
36 
FoxAndGo3 
引用:TopCoder - SRM594 Div1 Medium 
http://community.topcoder.com/stat?c=problem_statement&pm=12808&rd=15706 
囲碁っぽい問題。自分が黒番で好きなだけ黒石を 置ける。(死ぬ場所にも置けるので注意) 
黒石で白石のまわりを隙間なく囲めば白石を除い て領地(=空きマス)にすることができる。 
領地の最大値を求めよ。 
盤面の数は最大で50*50。また、白石同士は隣接 していない。
37 
そのまま置かなければ、領地は24 
◦本物の囲碁と違います
38 
黒石を置けば、白石がとれるけど、置いた分だけ 領地が21に減る。何もおかないほうが領地が24 で最大。
39 
このままでは領地は1
40 
黒石を真ん中に置くと、すべての白石が死に、自 分の領地になる。領地は4、これが最大値。
41 
初期の領地は10ですが、黒をうまく置くと、 最大領地は12になるようです。
42 
最大値を求める問題なので、このままでは 最小カットが使えない。 
◦黒石が最初からおいてあるところは絶対領地にできない 
◦つまり、仮の最大領地数=盤面の全マスー黒石数 
◦そこから逆に以下のように考える 
白石がとれなかったら、領地1の損失 
領地(空きマス)で黒石をおいたら、領地1の損失 
◦仮の最大領地数ー最小の領地損失=最大の領地数で求め ることができる。
43 
s 
t 
1 
0 
1 
0 
1 
0 
黒置く 
白死領地 
黒置く 
領地 
白のまま 
黒石は無視してよい。選択肢がないから。 
領地を1の損失と考えたこのグラフは正しい。 
「白死領地にするには、まわりに黒を置かない といけない」の制約をどうするか? 
領地 
白石と隣接する領地 (空きマス) 
白石
s 
t 
1 
0 
1 
0 
1 
0 
黒置く 
白死領地 
黒置く 
領地 
白のまま 
領地 
この2つを強制的に切らせたい
s 
t 
1 
0 
1 
0 
1 
0 
黒置く 
白死領地 
黒置く 
領地 
白のまま 
領地 
+∞ 
+∞
s 
t 
1 
0 
1 
0 
1 
0 
黒置く 
白死領地 
黒置く 
領地 
白のまま 
領地 
+∞ 
+∞ 
+∞の制約条件を入れても、最小カットが成立 してしまう。「黒置く」のところを強制的に カットさせたいのにできない。 
+∞のリンクを逆にしても、同じ。
47 
s 
t 
0 
0 
0 
1 
1 
1 
領地 
白死領地 
領地 
黒置く 
白のまま 
「黒置く」と「領地」の選択肢の順番を変える 
黒置く
48 
s 
t 
0 
0 
0 
1 
1 
1 
領地 
白死領地 
領地 
黒置く 
白のまま 
+∞の辺を白から領地の方向へ足す 
黒置く 
+∞ 
+∞
49 
s 
t 
0 
0 
0 
1 
1 
1 
領地 
白死領地 
領地 
黒置く 
白のまま 
黒置く 
+∞ 
+∞ 
こうすると、領地の辺をカットしても、 まだs-tは繋がっている。最小s-tカットになってい ないので、解にならない。 
◦つまり、元からの領地の部分に黒石をおかないのであれば、 白石を殺して領地にすることはできないという意味。
50 
s 
t 
0 
0 
0 
1 
1 
1 
領地 
白死領地 
領地 
黒置く 
白のまま 
黒置く 
+∞ 
+∞ 
仮に隣接する1カ所をカットしても まだs-tは繋がっている
51 
s 
t 
0 
0 
0 
1 
1 
1 
領地 
白死領地 
領地 
黒置く 
白のまま 
黒置く 
+∞ 
+∞ 
つまり、隣接する領地は、すべて「黒置く」を選ば ないと、s-tカットできない。 
「白石を殺して領地にするには、まわりに黒を置か ないといけない」という制約通りになってる。
52 
s 
t 
0 
0 
0 
1 
1 
1 
領地 
白死領地 
領地 
黒置く 
白のまま 
黒置く 
+∞ 
+∞ 
うっかり+∞の辺を領地から隣接する白方向に 足すと、うまくいかない。 
上の例で、「黒置く」をカットしなくても、s-t カットができている。
53 
s 
t 
0 
0 
0 
1 
1 
1 
領地 
白死領地 
領地 
黒置く 
白のまま 
黒置く 
+∞ 
+∞ 
うっかり+∞の辺を領地から隣接する白方向に 足すと、うまくいかない。 
上の例で、「黒置く」をカットしなくても、s-t カットができている。
54 
FoxAndGo3 
引用:TopCoder SRM594 Div1 Medium 
http://community.topcoder.com/stat?c=problem_statement&pm=12808&rd=15706 
囲碁っぽい問題。自分が黒番で好きなだけ黒石を 置ける。(死ぬ場所にも置けるので注意) 
黒石で白石のまわりを隙間なく囲めば白石を除い て領地(=空きマス)にすることができる。 
領地の最大値を求めよ。 
盤面の数は最大で50*50。また、白石同士は隣接 していない。←この条件があると、囲む判定を工 夫する必要がありますが、それでも解けます。
55
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 
青が4点。青同士が隣合うと-1点。 
最高点がとれるように?の色を青か白にせよ。
58 
最大値問題から最小値問題への置き換えをする。 
◦?のマスは元から4点取ってることにする。 
◦?を白にしたら、4点減点。 
s 
t 
4 
0 
白にする 
青にする 
?
59 
?と隣接する青マスに対して、 
◦?が青になったときは、1点減点 
◦?が白になったときは、何もしない 
s 
t 
4 
0 
白にする 
青にする 
?
60 
sから青マスへ+∞の辺をつなげる。 
◦+∞の辺を、s,tのどちら側につなげても良いが、制約条 件を考えること。 
今回のようにsと青マスをつないだ場合は、青マ スから?へコスト2を足すとよい。 
◦青マス、?マスの両方でコスト1ずつ損するので、コス ト2になる。 
s 
t 
4 
0 
白にする 
青にする 
? 
+∞ 
2
61 
?-?間の制約条件 
s 
t 
4 
0 
白にする 
青にする 
? 
? 
青にする 
0 
白にする 
4
62 
?を両方青にしても、s-tカットできる。 
◦コスト2を課すことができない。 
s 
t 
4 
0 
白にする 
青にする 
? 
? 
青にする 
0 
白にする 
4 
2
63 
逆向きにしても、s-tカットできるのでダメ。 
s 
t 
4 
0 
白にする 
青にする 
? 
? 
青にする 
0 
白にする 
4 
2
64 
両向きにしても、s-tカットできるのでダメ。 
s 
t 
4 
0 
白にする 
青にする 
? 
? 
青にする 
0 
白にする 
4 
2
65 
グリッドグラフは二部グラフである。 
◦EVEN同士とODD同士がつながることはない。 
マスをEVENとODDで区別すれば、先ほどの問題 は解決できる 
EVEN:(x+y)%2==0 
ODD:(x+y)%2==1
66 
◦ODDのマスに対して、3章で学んだ、選択肢を並べ替え るテクニックを使う 
◦このようにすると、両方とも青にするをカットしても、 s-tカットにならない。コスト2の辺もカットする必要が ある。 
s 
t 
4 
4 
白にする 
青にする 
? 
? 
白にする 
0 
EVEN 
ODD 
0 
青にする 
2
67 
s 
t 
4 
4 
白にする 
青にする 
? 
? 
白にする 
0 
EVEN 
ODD 
0 
青にする 
2 
+∞ 
2 
ODD 
EVEN 
2 
+∞ 
◦ODD側の青マスからt側に+∞の辺を足す。 
これでグラフが完成です。
http://ideone.com/wsv2RY 
プログラミングコンテストチャレンジブックでは 白マスもでてきますが、必要ありません。 
68
69
70 
Surrounding Game 
引用:TopCoder - SRM558 Div1 Hard https://code.google.com/codejam/contest/32011/dashboard#s=p4 
長方形の盤面(最大20マス*20マス)があり、す べてのマスに利益biと費用ciが割り当てられてい る。 
◦マスに石を置くか、全ての隣接するマスに石を置くと、 利益biが得られる。 
◦マスに石を置くと、費用ciがかかる 
スコア=全利益-全費用とする。スコアを最大化 せよ。
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 
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 
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 
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
制約条件が難しいので、まずは、1マスだけ考え る 
◦マスに石を置くか、全ての隣接するマスに石を置くと、 利益が得られる。→ OR の条件がやっかい 
◦マスに石を置くと、費用がかかる。 
75
76 
まず、選択肢として、置く・置かないはある 
最小値問題にする 
◦bi-ci>0のとき、元からbi-ciのもらえてるとすれば、置い たときはコスト0、置かないときはbi-ci 
s 
t 
置く 
0 
置かない 
bi-ci
77 
まず、選択肢として、置く・置かないはある 
最小値問題にする 
◦bi-ci<0のとき、損失するか0のままなので、置いたとき はコストci-bi、置かないときは0 
s 
t 
置く 
ci-bi 
置かない 
0
78 
ここから先はbi-ci>0ときだけのグラフを書きます。 
◦bi-ci>0でもci-bi>0でも、グラフの形はかわらず、コス トが違うだけ。あまり影響はない。
79 
他に、囲まれる・囲まれないという状態もある。 
1つのマスごとに、2つの頂点を使えば、良いのでは ないか? 
囲む・囲まれないは、元からbiもらえてることにする。 
これでいいの? 
s 
置 く 
t 
置く 
置かない 
0 
囲 む 
囲まれない 
bi 
囲まれる 
0 
bi-ci
80 
これはダメ。 
「置く」かつ「囲まれる」でs-tカットできる 
◦「置く」かつ「囲まれる」で利益の2重どり(2bi-ci)に なってしまう。 
s 
置 く 
t 
置く 
置かない 
bi-ci 
0 
囲 む 
囲まれない 
bi 
囲まれる 
0
81 
「囲む」から「置く」へコスト+∞の辺を追加 
「置く」かつ「囲まれる」は許されなくなる。 
◦もとから無意味な状態(「囲まれる」場所に「置く」メ リット)はないので、強制的に除外しても構わない。 
s 
置 く 
t 
置く 
置かない 
bi-ci 
0 
囲 む 
囲まれない 
bi 
囲まれる 
0 
+∞
82 
s 
置 く 
t 
置く 
置かない 
bi-ci 
0 
囲 む 
囲まれない 
bi 
囲まれる 
0 
+∞ 
EVEN (偶数マス) 
ODD 
(奇数マス) 
置 く 
置く 
置かない 
bi-ci 
0 
囲 む 
囲まれない 
bi 
囲まれる 
0 
+∞ 
「囲まれるには、周り全てに置く必要がある」 の制約条件を入れる準備として、奇数ODDマスの選択 肢をすべて逆にする。
83 
s 
置 く 
t 
置く 
置かない 
bi-ci 
0 
囲 む 
囲まれない 
bi 
囲まれる 
0 
+∞ 
置 く 
置く 
置かない 
bi-ci 
0 
囲 む 
囲まれない 
bi 
囲まれる 
0 
+∞ 
EVEN (偶数マス) 
ODD (奇数マス) 
「囲まれる」とき「隣に置かない」のは禁止なので これらを選んだ時にs-tカットができないように+∞ の辺を貼ればよい。 
+∞ 
+∞
http://ideone.com/9kZXjO 
84
85
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点得られる. 
スコアを最も多く得られるようなビット列を求め よ.
公式の解説もぜひ参考にしてください。 http://www.slideshare.net/oupc/h1- 17155052 
87
各ビットごとに、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 
ビット列
ビットが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 
ビット列
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個
この場合、合計点は、 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]
これまでの問題のように、グラフをつくれるが… 
◦ビット1かビット0かの選択。元からai点もらえること にしておいて、ビット0のときに損失ai点となるように する。 
「距離w以内にある1の個数が奇数のときbi点」の 条件の追加が難しい。 
◦グラフで考えたら、「ビット1を選択したカットの数を 数える」という処理が必要になり、たぶん不可能。 
92
ビット列の累積和(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]
累積和xを使えば、制約条件も簡単になる。 
◦x[i+w+1]-x[i-w]=1ならbi点 
mod2なので、奇数個なら1 
◦x[i+1]-x[i]=1ならai点 
2つの項の関係なら、最小カット用のグラフに、 制約条件いれることが簡単にできる。 
94
あらかじめai,bi全ての得点をもらえたことにして、 最小化問題に置き換える。 
端の処理が難しいので、前後にw個の番兵をいれ る。番兵の部分は範囲外で、ビット1を数えると きに影響を与えないようにしたいので、ビット0 とする。 
◦k={0.....0??.......??0.....0} 
95 
w個 
w個 
n個
累積和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 
次のページからのグラフはn=4、w=1のケースで す。
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 
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 
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
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 
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にする
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にする」をすでに選択した(=カットした)とみな すので、辺は不要。
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にする 
+∞ 
+∞
累積和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個 
元のビットの部分だけど(番兵ではない) 値が決まっているのに注意。
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 
+∞ 
+∞ 
+∞ 
+∞
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 
+∞ 
+∞ 
+∞ 
+∞
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にする」が +∞の辺
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の辺は省きました。
ノードsから辿れる範囲を求める(これ以上流せ ないところcap=0は、リンクがなくなる) 
◦ノードsから幅優先探索すればよい。 
流し終わったあと 
◦sourceからたどれる範囲が、最小カット時のs側。 
◦たどれないほうがt側。その境界がカットするところ。 
復元するときは、 
◦x[奇数]・x[偶数]の0,1が互い違いになってること 
◦求めるべきなのはkなので、xの差をとることを忘れない。 
110
http://ideone.com/7SiimG 
111
112
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 
兎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の表
「効率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(求めたいのはこれ)
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 もっと下
割り算を避けるために、二分探索の形にして、両辺 に分母をかけて、整数問題として扱うというテク ニックは、プログラミングコンテストチャレンジ ブック第2版P132「平均最大化」も参考にしてく ださい。 
117
118 
푃 퐶 > 푎 푏 
푏푃−푎퐶>0 푏 푝푖푗 퐺 푖<푗 −푎퐾200−퐾>0 
P/C>a/bを数式変形すると、以上のようになる。 
◦Kは、選んだウサギの数。 
◦Gはウサギの集合。i<jとなるpijの数は、K(K-1)/2。 
◦最小カットに持ち込むなら、このKの値が、辺のコス トに入らないようにしたい。
119 
s 
ペア 01 
t 
雇う 
組合わせなし 
雇う 
雇わない 
組み合わせあり 
雇わない 
兎 0 
兎 1 
グラフは以上のように なりそう(K=1の場合) 
1辺のコストにKを使いたくないので (全コスト)=(辺の数)*(1辺のコスト) の形にして、辺の数側にKを組み込んでしまう。 
ウサギペアはK(K-1)/2、ウサギの数はK 
K(K-1)/2 *(???) +K*(???) の形であれば最小カットに持ち込める。
以上のように数式変形すると 
◦ウサギペア K(K-1)/2箇所の辺に、bpij+2aのコスト 
i<jを満たすのが、 K(K-1)/2個あるので、これでよい。 
◦ウサギ K箇所の辺に 199aのコスト 
左辺の最大値>0となればいいので、左辺を最小 カットする。 
120 
数式はTopCoder公式解説の ものです.
121 
s 
ペア 01 
t 
雇う 
199a 
組合わせなし 
bp01+2a 
雇う 199a 
雇わない 0 
組み合わせあり 
0 
兎 0 
兎 1 
組み合わせあり・なしについては、組み合わせ ありの利益→組み合わせなしの損失に置き換え。 
「組み合わせあり」を選んだときは、「雇う」 を選ばせたいので、制約条件の+∞の辺を追加 する。 
雇わない 
0 
+∞ 
+∞
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
http://ideone.com/8QljRJ 
123
124 
終わり ここまで読んでくださり ありがとうございました 質問・提案などありましたら Twitterの@nico_shindanninまでお願いします。
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
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 
「何を選択するか」を取り扱うのに、2つ方法が あるので、悩んだ 
1.ノードが、s側に属するか、t側に属するかで、選択肢 を割り振る(たいていの他の資料の方法) 
3択以上の選択肢、直列に辺がならぶとき(そういう問題 はでてきてないけど)、分かりづらい? 
2.辺に、選択肢を割り当て、辺をカットしたら選択した ということにする(本文の方法) 
6章の問題のような、カットする選択肢となる辺のコストが 全て0になるときに、説明が不十分かも→でも、いまから全 部直せない…。 
min-cutを定式化すると、 푐푖푗푑푖푗(푖,푗)∈퐸の形なので、辺に選 択肢が直結してたほうが、直感的かもと思った。
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さんのページのほうがずっと良いので、自分が 説明しないほうが良い気もしました(泣)

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