Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Chargement dans…3
×
1 sur 20

paizaオンラインハッカソン(略してPOH![ポー!])Lite「天才火消しエンジニア霧島 もしPMおじさんが『丸投げ』を覚えたら」解説

0

Partager

Télécharger pour lire hors ligne

paizaオンラインハッカソン(略してPOH![ポー!])Lite「天才火消しエンジニア霧島 もしPMおじさんが『丸投げ』を覚えたら」解説

Livres associés

Gratuit avec un essai de 30 jours de Scribd

Tout voir

paizaオンラインハッカソン(略してPOH![ポー!])Lite「天才火消しエンジニア霧島 もしPMおじさんが『丸投げ』を覚えたら」解説

  1. 1. paizaオンラインハッカソン(略して POH![ポー!])Lite「天才火消しエン ジニア霧島 もしPMおじさんが『丸投 げ』を覚えたら」解説 ギノ株式会社 吉岡
  2. 2. 問題 https://paiza.jp/poh/kirishima
  3. 3. 問題 • 人数(q)と費用(r)の組みがn個ある。 • 合計 m人 以上の組み合わせを探す。 • その中で最低の費用を出力する。 • 1≤n≤ 50 1≤q≤ 10,000 1≤r≤ 5,000,000 1≤m≤ 200,000
  4. 4. 解法1(全探索) • 各社について、使う・使わないの全組み合わせ を走査する。 • 合計がm人以上の組み合わせか判定する。 • その中で、一番小さい組み合わせを探す。
  5. 5. コード例1-1 (全探索、再帰)
  6. 6. @m = gets.to_i @n = gets.to_i @companies = [] @n.times{ q, r = gets.split.map(&:to_i) @companies.push([q, r]) } def calc(i, engineers, cost) if i == @n if engineers >= @m return cost else return 999999999999 end end ret1 = calc(i+1, engineers, cost) ret2 = calc(i+1, engineers+@companies[i][0], cost +@companies[i][1]) return [ret1, ret2].min end puts calc(0, 0, 0)
  7. 7. コード例1-2 (全探索、ビット演算) 10進数2進数(0埋め3桁) 0 000 1 001 2 010 3 011 4 100 5 101 6 110 7 111
  8. 8. @m = gets.to_i @n = gets.to_i @companies = [] @n.times{ q, r = gets.split.map(&:to_i) @companies.push([q, r]) } mincost = 99999999999 (0..2**@n).each{|i| engineers = 0 cost = 0 (0...@n).each{|j| if (i & (1<<j) != 0) then engineers += @companies[j][0] cost += @companies[j][1] end } if engineers >= @m mincost = [mincost, cost].min end } puts mincost
  9. 9. 計算量 • 計算量(Complexity)とは? • O(x): 定数倍の差を無視した計算量 • O(g(n)) = {f(n): ある正の定数c, n0が存在して、 すべてのn>n0に対して0≤f(n)≤cg(n)を満たす} • アルゴリズムの効率の評価に多く使われる
  10. 10. 計算量 • 各社、「使う」「使わない」の2通り • 2^n通りの組み合わせ => 2^n に比例した時間がかかる。 => 計算量: O(2^n) • n=50なので、合計1,125,899,906,842,624通 り
  11. 11. 効率は上げれないか?
  12. 12. 解法2 (動的計画法) • 動的計画法とは 問題を解いていく途中の結果を記録しておき、 再利用することで効率を上げる方法
  13. 13. 解法2 (動的計画法) • 最大人数をサイズとするメモ配列(DP[人数])を用 意し、コストを記録していく。 • 各会社をループ • 各メモ配列(DP)をループ • DP[メモ配列の人数+会社の人数] =MIN(メモ配列のコスト + 会社のコスト, DP[メモ配列の人数+会社の人数])
  14. 14. コード
  15. 15. m = gets.to_i n = gets.to_i dp = Array.new(m+1, 9999999999999) dp[0] = 0 n.times{ q, r = gets.split.map(&:to_i) m.downto(0).each{|i| q2 = [i+q, m].min dp[q2] = [dp[q2], dp[i]+r].min } } puts dp[m]
  16. 16. 計算量 • 会社数(m) x 最大人数(n) がループ回数 • O(m x n) • 最大ループ回数: 10,000,000 回
  17. 17. 参考 • 詳しくはblog 『もし先輩女子エンジニアが『アルゴリズム』 を図解で教えてくれるとしたら』 http://paiza.hatenablog.com/entry/2014/09/11/%E3%82%82%E3%81%97%E5%85%88%E8%BC%A9%E5%A5%B3%E5%AD %90%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%8C%E3%80%8E%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA %E3%83%A0%E3%80%8F%E3%82%92%E5%9B%B3

×