20141203 第5回社内勉強会(佐藤)

30
第5回 社内勉強会 担当 佐藤

Transcript of 20141203 第5回社内勉強会(佐藤)

Page 1: 20141203 第5回社内勉強会(佐藤)

第5回 社内勉強会担当 佐藤

Page 2: 20141203 第5回社内勉強会(佐藤)

今日のテーマ の前に…

Page 3: 20141203 第5回社内勉強会(佐藤)

まず5分間だけ 考えてみよう

Page 4: 20141203 第5回社内勉強会(佐藤)

n個の仕事があります。 各仕事は時間siにはじまり、時間tiに終わります。あなたは各仕事について、参加するか参加しないかを選ばなければなりません。 仕事に参加するならば、その仕事のはじめから終わりまで参加しなければなりません。 また、参加する仕事の時間帯が重なってはなりません。(開始の瞬間・終了の瞬間だけが重なるのも許されません) できるだけ多くの仕事に参加したいです。何個の仕事に参加することができるでしょうか。 制約 1 ≦ N ≦ 100000 1 ≦ si ≦ 109

問題

Page 5: 20141203 第5回社内勉強会(佐藤)

例入力 n = 5, s = {1, 2, 4, 6, 8}, t = {3, 5, 7, 9, 10}

出力 3 (仕事1, 3, 5を選択)

仕事1

仕事2

仕事3

仕事4

仕事5

Page 6: 20141203 第5回社内勉強会(佐藤)

テーマ発表!!

Page 7: 20141203 第5回社内勉強会(佐藤)

貪欲法

Page 8: 20141203 第5回社内勉強会(佐藤)

貪欲法とは

一つのルールに従って、 貪欲的に「その場での最善」を選択することを 繰り返すというアルゴリズム設計技法のこと。

Page 9: 20141203 第5回社内勉強会(佐藤)

例1円玉, 5円玉, 10円玉, 50円玉, 100円玉, 500円玉が それぞれ、C1, C5, C10, C50, C100, C500枚ずつあります。 できるだけ少ない枚数の硬貨 でA円を支払いたいと考えています。何枚の硬貨を出す必要があるでしょうか? なお、そのような支払い方は少なくとも一つは存在するとします。 制約 0 ≦ C1, C5, C10, C50, C100, C500 ≦ 109 0 ≦ A ≦ 109

Page 10: 20141203 第5回社内勉強会(佐藤)

解答:アルゴリズム

• 大きな額の硬貨から優先的に使う

Page 11: 20141203 第5回社内勉強会(佐藤)

解答: ソース//コインの金額 const int V[6] = {1, 5, 10, 50, 100, 500};

//入力 int C[6]; // C[0] = C_1, C[1] = C_5, ・・・

void solve() { int ans = 0; for (int i = 5; i >= 0; i- -) { int t = min(A/V[i], C[i]);//コインiを使う枚数 A -= t * V[i]; ans += t; }

printf(“%d\n”, ans); }

Page 12: 20141203 第5回社内勉強会(佐藤)

参考

http://www.itmedia.co.jp/enterprise/articles/1009/04/news002.html

Page 13: 20141203 第5回社内勉強会(佐藤)

もう一回 thinking time !

Page 14: 20141203 第5回社内勉強会(佐藤)

n個の仕事があります。 各仕事は時間siにはじまり、時間tiに終わります。あなたは各仕事について、参加するか参加しないかを選ばなければなりません。 仕事に参加するならば、その仕事のはじめから終わりまで参加しなければなりません。 また、参加する仕事の時間帯が重なってはなりません。(開始の瞬間・終了の瞬間だけが重なるのも許されません) できるだけ多くの仕事に参加したいです。何個の仕事に参加することができるでしょうか。 制約 1 ≦ N ≦ 100000 1 ≦ si ≦ 109

問題

Page 15: 20141203 第5回社内勉強会(佐藤)

例入力 n = 5, s = {1, 2, 4, 6, 8}, t = {3, 5, 7, 9, 10}

出力 3 (仕事1, 3, 5を選択)

仕事1

仕事2

仕事3

仕事4

仕事5

Page 16: 20141203 第5回社内勉強会(佐藤)

解答:アルゴリズム

• 選べる仕事の中で、終了時間が最も早いものを選ぶことを繰り返す

Page 17: 20141203 第5回社内勉強会(佐藤)

解答: ソース(2段ですまぬ)const int MAX_N = 100000; //入力 int N, S[MAX_N], T[MAX_N];

//仕事をソートするためのpairの配列 pair<int, int> itv[MAX_N];

void solve() { //pairは辞書順で比較される //終了時間の早い順にしたいため、Tをfirstに、Sをsecondにいれる。 for (int i = 0; i < N; i++) { itv[i].first = T[i]; itv[i].second = S[i]; } sort(itv, itv + N);

//tは最後に選んだ仕事の終了時間 int ans = 0, t = 0; for (int i = 0; i < N; i++){ if (t < itv[i].second) { ans++; t = itv[i].first; } } printf(“%d\n”, ans); }

Page 18: 20141203 第5回社内勉強会(佐藤)

ダメな例• 選べる仕事の中で開始時間が最も早いものを選ぶことを繰り返す。

• 選べる仕事の中で、時間が最も短いものを選ぶことを繰り返す。

• 選べる仕事の中で、その仕事を選んだ時に選べなくなる他の仕事の数が最も少ないものを選ぶことを繰り返す。

Page 19: 20141203 第5回社内勉強会(佐藤)

さて ここからが勉強だ

Page 20: 20141203 第5回社内勉強会(佐藤)

いい例とダメな例 その差はなんだろう

Page 21: 20141203 第5回社内勉強会(佐藤)

そもそも貪欲法は 「その場で最善」 を繰り返す

Page 22: 20141203 第5回社内勉強会(佐藤)

けど、 「全体で最善」

かどうかはわかんない

Page 23: 20141203 第5回社内勉強会(佐藤)

つまり

Page 24: 20141203 第5回社内勉強会(佐藤)

貪欲法に従ったアルゴリズムは 計算量を激減できるけど 正しい保証がない!!

Page 25: 20141203 第5回社内勉強会(佐藤)

じゃあ、 どうやって正解を導く?

Page 26: 20141203 第5回社内勉強会(佐藤)

ごめん、 そこまで考える時間なかった

Page 27: 20141203 第5回社内勉強会(佐藤)

さっきの参考ページにも センスと経験だとか 書いてあったしorz

Page 28: 20141203 第5回社内勉強会(佐藤)

じゃあ、どうすんの?

Page 29: 20141203 第5回社内勉強会(佐藤)

とりあえず、利用は プログラミングコンテストに絞ろう 今の俺らが製品に使うには怖すぎる

Page 30: 20141203 第5回社内勉強会(佐藤)

おわり