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

Post on 14-Apr-2017

369 views 0 download

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

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

今日のテーマ の前に…

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

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

問題

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

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

仕事1

仕事2

仕事3

仕事4

仕事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

解答:アルゴリズム

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

解答: ソース//コインの金額 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); }

参考

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

もう一回 thinking time !

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

問題

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

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

仕事1

仕事2

仕事3

仕事4

仕事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); }

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

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

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

さて ここからが勉強だ

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

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

けど、 「全体で最善」

かどうかはわかんない

つまり

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

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

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

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

じゃあ、どうすんの?

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

おわり