1 / 29

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

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). シャーレ.

Download Presentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 2011/02/12 国立オリンピック記念青少年総合センター 第 10 回 日本情報オリンピック本戦 問題5微生物実験 (Bug Party) 東京大学 理学部 情報科学科 4 年 メキシコ大会(2006) 日本代表 秋葉 拓哉/ [[iwi]]

  2. 問題概要 微生物 fooの放出と吸収 放出 5 10 6 foo(有害物質) 5 + 10 + 6 = 21 できるだけ多く 選びたい 7 7 7 摂取 どれも死なない (許容量:9, 12, 7) シャーレ

  3. O(N2) の解法

  4. アイディア • foo許容量が最低の奴が必ず最初に死ぬ • 残りの奴らの許容量はどうでも良い foo許容量 は,選ぶ 微生物の中で最低の物のみに注目

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

  6. 選べる微生物が決まる 赤色の部分の奴らだけ選べる 最低 ライン

  7. どれを選べばよいか? 放出量が小さいやつから貪欲に,選べるだけ選ぶ 最低 ライン

  8. 何故,貪欲的に選んで OK? • 許される合計の放出量は選び方によらない • foo許容量の最低ラインを xとする • k匹選ぶなら,foo放出量は合計 kxまで OK • なら放出量の合計をできるだけ小さくしたい → 放出量が小さい方から選べば良い

  9. 愚直に実装 → 計算量は? • foo許容量の最低ラインの候補は? • N通り (b0, b1, …, bN) • 最低ラインの各候補に対して • 最高で N個まで選ぶ • よって O(N2)

  10. O(N log2N) の解法

  11. アイディア 二分探索ができそう • 許容量の最低ラインを固定したとき • 放出量の小さい方から,どこまで選べるか? • 「ここまで選べるか」が効率的に判定できれば OK しかし,効率的に判定できるの…?

  12. アイディア 最低ラインが少し変わった時, 状況も少ししか変わらない 1 つ選べる放出量が増えた

  13. アイディア 二分探索ができそう データ構造 を活用して実現 最低ラインが少し変わった時, 状況も少ししか変わらない

  14. 処理の順番 許容量の最低ラインをだんだん減らそう

  15. 実現したいこと • 二分探索 • foo放出量最低ラインを biにしたとき • 「何人入れられるか?」を効率的に求める • 更新 • 新たに選べる放出量 aiを追加する

  16. Binary Indexed Tree • 数の列を管理するデータ構造 • O(log n) で,以下ができます • ある場所に値を足す • ある場所までの和(累積和)を求める

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

  18. Binary Indexed Tree • 値の加算 • 累積和の計算 void add(inti, intv) {for (; i <= n; i += i & -i) bit[i] += v;} int sum(inti, int *bit) {ints = 0;for (; i > 0; i -= i & -i) s += bit[i];return s;}

  19. Binary Indexed Tree • 値の加算 • 累積和の計算 !? void add(inti, intv) {for (; i <= n; i += i & -i) bit[i] += v;} int sum(inti, int *bit) {ints = 0;for (; i > 0; i -= i & -i) s += bit[i];return s;}

  20. Binary Indexed Tree • 値の加算 • 累積和の計算 君たちは void add(inti, intv) {for (; i <= n; i += i & -i) bit[i] += v;} int sum(inti, int *bit) {ints = 0;for (; i > 0; i -= i & -i) s += bit[i];return s;}

  21. Binary Indexed Tree • 値の加算 • 累積和の計算 君たちは void add(inti, intv) {for (; i <= n; i += i & -i) bit[i] += v;} 良い時代に int sum(inti, int *bit) {ints = 0;for (; i > 0; i -= i & -i) s += bit[i];return s;}

  22. Binary Indexed Tree • 値の加算 • 累積和の計算 君たちは void add(inti, intv) {for (; i <= n; i += i & -i) bit[i] += v;} 良い時代に int sum(inti, int *bit) {ints = 0;for (; i > 0; i -= i & -i) s += bit[i];return s;} 生まれました!

  23. Binary Indexed Tree の使い方 • 放出量をキーとする 2 本の BIT を管理 • Bit0: 微生物の個数 • Bit1: 微生物の放出量

  24. Binary Indexed Tree の使い方 • 放出量 yのやつまで入れられるかな? • 放出量の和 • Bit1 の yまでの累積和 • 許せる放出量 • 匹数は Bit0 の yまでの累積和なので • x × (Bit0 の yまでの累積和) 1. 放出量の和 ≦ 2. 許せる放出量 ならOK

  25. O(n log2n) の別解 • 何匹入れるかで二分探索 • k匹入れると決めたら, • やはり許容量の最低ラインを減らしながら • 放出量が最低の k匹を管理する

  26. O(N log n) の解法

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

  28. おわり お疲れ様でした

More Related