29
第 10 第 第第第第第第第第第第第第 第第 5 第第第第第 (Bug Party) 第第第第 第第第 第第第第第 4 第 第第第第第第 (2006) 第第第第 第第 第第 / [[iwi]] 2011/02/12 第第第第第第第第第第第第第第第第第第第

第 10 回 日本情報オリンピック本戦 問題 5 微生物実験 (Bug Party)

Embed Size (px)

DESCRIPTION

2011/02/12 国立オリンピック記念青少年総合センター. 第 10 回 日本情報オリンピック本戦 問題 5 微生物実験 (Bug Party). 東京大学 理学部 情報科学科 4 年 メキシコ大会 (2006) 日本代表 秋葉 拓哉 / [[ iwi ]]. 問題概要. 微生物. foo の放出と吸収. 放出. 5. 10. 6. foo ( 有害物質 ) 5 + 10 + 6 = 21. できるだけ多く 選びたい. 7. 7. 7. 摂取. どれ も死なない ( 許容量: 9, 12, 7). シャーレ. - PowerPoint PPT Presentation

Citation preview

Page 1: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

第 10 回 日本情報オリンピック本戦 問題 5

微生物実験 (Bug Party)

東京大学 理学部 情報科学科 4 年メキシコ大会 (2006) 日本代表

秋葉 拓哉 / [[iwi]]

2011/02/12 国立オリンピック記念青少年総合センター

Page 2: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

問題概要

番号 1 2 3 4 5 6

放出量 ai12 5 2 10 6 13

許容量 bi8 9 4 12 7 9

シャーレ

微生物

できるだけ多く選びたい

  foo ( 有害物質 )

  5 + 10 + 6 = 21

放出5 10 6

7 7 7摂取

どれも死なない ( 許容量: 9, 12, 7)

foo の放出と吸収

Page 3: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

O(N2) の解法

Page 4: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

アイディア

• foo 許容量が最低の奴が必ず最初に死ぬ

• 残りの奴らの許容量はどうでも良い

foo 許容量 は,選ぶ微生物の中で最低の物のみに注目

Page 5: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

許容量の最低ラインを固定

許容量の最低ラインを固定してみる?

放出量

許容量

最低ライン

Page 6: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

選べる微生物が決まる

赤色の部分の奴らだけ選べる

放出量

許容量

最低ライン

Page 7: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

どれを選べばよいか?

放出量が小さいやつから貪欲に,選べるだけ選ぶ

放出量

許容量

最低ライン

Page 8: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

何故,貪欲的に選んで OK?

• 許される合計の放出量は選び方によらない– foo 許容量の最低ラインを x とする– k 匹選ぶなら, foo 放出量は合計 kx まで OK

• なら放出量の合計をできるだけ小さくしたい→ 放出量が小さい方から選べば良い

Page 9: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

愚直に実装 → 計算量は?

• foo 許容量の最低ラインの候補は?– N 通り (b0, b1, …, bN)

• 最低ラインの各候補に対して–最高で N 個まで選ぶ

• よって O(N2)

Page 10: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

O(N LOG2 N) の解法

Page 11: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

アイディア

• 許容量の最低ラインを固定したとき– 放出量の小さい方から,どこまで選べるか?– 「ここまで選べるか」が効率的に判定できれば OK

しかし,効率的に判定できるの…?

二分探索ができそう

Page 12: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

アイディア

1 つ選べる放出量が増えた

最低ラインが少し変わった時,状況も少ししか変わらない

Page 13: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

アイディア

データ構造を活用して実現

最低ラインが少し変わった時,状況も少ししか変わらない

二分探索ができそう

Page 14: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

処理の順番

許容量の最低ラインをだんだん減らそう

放出量

許容量

Page 15: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

実現したいこと

• 二分探索– foo 放出量最低ラインを bi にしたとき–「何人入れられるか?」を効率的に求める

• 更新–新たに選べる放出量 ai を追加する

Page 16: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

Binary Indexed Tree

• 数の列を管理するデータ構造

• O(log n) で,以下ができます–ある場所に値を足す–ある場所までの和 ( 累積和 ) を求める

Page 17: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

Binary Indexed Tree

ビット演算を活用し,非常に簡潔に実装できる

Page 18: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

Binary Indexed Tree

• 値の加算

• 累積和の計算

void add(int i, int v) {  for (; i <= n; i += i & -i) bit[i] += v;}

int sum(int i, int *bit) {  int s = 0;  for (; i > 0; i -= i & -i) s += bit[i];  return s;}

Page 19: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

Binary Indexed Tree

• 値の加算

• 累積和の計算

void add(int i, int v) {  for (; i <= n; i += i & -i) bit[i] += v;}

int sum(int i, int *bit) {  int s = 0;  for (; i > 0; i -= i & -i) s += bit[i];  return s;}

!?

Page 20: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

Binary Indexed Tree

• 値の加算

• 累積和の計算

void add(int i, int v) {  for (; i <= n; i += i & -i) bit[i] += v;}

int sum(int i, int *bit) {  int s = 0;  for (; i > 0; i -= i & -i) s += bit[i];  return s;}

君たちは

Page 21: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

Binary Indexed Tree

• 値の加算

• 累積和の計算

void add(int i, int v) {  for (; i <= n; i += i & -i) bit[i] += v;}

int sum(int i, int *bit) {  int s = 0;  for (; i > 0; i -= i & -i) s += bit[i];  return s;}

君たちは良い時代に

Page 22: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

Binary Indexed Tree

• 値の加算

• 累積和の計算

void add(int i, int v) {  for (; i <= n; i += i & -i) bit[i] += v;}

int sum(int i, int *bit) {  int s = 0;  for (; i > 0; i -= i & -i) s += bit[i];  return s;}

君たちは良い時代に

生まれました!

Page 23: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)
Page 24: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

Binary Indexed Tree の使い方

• 放出量をキーとする 2 本の BIT を管理– Bit0: 微生物の個数– Bit1: 微生物の放出量

放出量 1 2 3 4 5 6 7 8 ...

Bit0 0 1 0 1 1 0 1 0 ...Bit1 0 2 0 4 5 0 7 0 ...

Page 25: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

Binary Indexed Tree の使い方

• 放出量 y のやつまで入れられるかな?

1. 放出量の和– Bit1 の y までの累積和

2. 許せる放出量–匹数は Bit0 の y までの累積和なので– x × (Bit0 の y までの累積和 )

1. 放出量の和≦

2. 許せる放出量なら OK

Page 26: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

O(n log2 n) の別解

• 何匹入れるかで二分探索

• k 匹入れると決めたら,–やはり許容量の最低ラインを減らしながら–放出量が最低の k 匹を管理する

Page 27: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

O(N LOG N) の解法

Page 28: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

Binary Indexed Tree の構造を活用する

二分探索を Binary Indexed Tree の構造に沿って行うようにすればよい

Page 29: 第  10  回 日本情報オリンピック本戦 問題 5 微生物実験  (Bug Party)

おわりお疲れ様でした