動的計画法

10,657 views

Published on

競技プログラミング練習会2014 Normalで使ったスライドです。基本的な動的計画法の考え方について説明しています。

Published in: Technology
0 Comments
12 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
10,657
On SlideShare
0
From Embeds
0
Number of Embeds
1,361
Actions
Shares
0
Downloads
41
Comments
0
Likes
12
Embeds 0
No embeds

No notes for slide

動的計画法

  1. 1. 動的計画法
  2. 2. 動的計画法 ●問題を複数の部分問題に分割して、部分問題の 計算結果を利用して元の問題を解く手法 ●効率的なアルゴリズムを作るときによく使われ る一般的な方法
  3. 3. 動的計画法 ●例 フィボナッチ数の計算 ●フィボナッチ数の定義通りプログラムを書くと こうなる int fib(unsigned int n) { if (n == 0) return 0; if (n == 1) return 1; return fib(n-1) + fib(n-2); } F0=0, F1=1, Fn=Fn−1+Fn−2 (n≥2)
  4. 4. 動的計画法 ●これだと、   ぐらいまでしか計算できない ●     の指数時間アルゴリズム n = 40 fib(8) =fib(7) + fib(6) =(fib(6) + fib(5)) + (fib(5) + fib(4)) =((fib(5) + fib(4)) + (fib(4) + fib(3)) + ((fib(4) + fib(3)) + (fib(3) + fib(2))) =(((fib(4) + fib(3)) + (fib(3) + fib(2))) + ((fib(3) + fib(2)) + (fib(2) + fib(1))) + (((fib(3) + fib(2)) + (fib(2) + fib(1)) + ((fib(2) + fib(1)) + (fib(1) + fib(0))) O(1.619n )
  5. 5. 動的計画法 ●計算過程を見ると、何回も同じ引数で函数を呼 び出している ●この函数は同じ引数なら常に同じ値を返すか ら、一度計算した内容を再利用すれば良さそう ●これが動的計画法の基本的アイデア
  6. 6. 動的計画法 ●改良版フィボナッチ数の計算 int fib(unsigned int n) { vector<int> ary(n+1); ary[0] = 0; ary[1] = 1; for(int i = 2; i <= n; ++i) ary[i] = ary[i-1] + ary[i-2]; return ary[n]; }
  7. 7. 動的計画法 ●  の線形時間アルゴリズムになった ●    ぐらいまで対応できる ●もっとも、   ぐらいでint型の整数だとオーバー フローする ● 番目のフィボナッチ数を定数 で割った余りを求 める問題などでつかえる ●実際には対数時間アルゴリズムも存在する O(n) n = 107 n = 47 n k
  8. 8. 動的計画法 ●動的計画法が有効な問題の一つがナップサック 問題 ●問題パターンとしてはよく出題される ●社会での実用上も大事な問題
  9. 9. ナップサック問題 ● 個の荷物があり、それぞれ価値 、体積 で ある。 ●容積 のナップサックがある。 ●体積の合計が を超えない範囲で荷物を詰めた とき、その価値の合計の最大値はいくつか? ●条件 n Pi Vi C C 1≤n≤1,000 1≤Pi≤1,000,000,000 1≤V i≤1,000 1≤C≤1,000
  10. 10. ナップサック問題 価値 55 体積 40 価値 82 体積 97 価値 38 体積 19 価値 63 体積 32 価値 61 体積 26 容積 150
  11. 11. ナップサック問題 ●ナイーブ(ばか正直)な解法 ●それぞれの荷物について、ナップサックに入れるか 入れないかの2通りを調べる ●体積の合計が を越えない入れ方の中で、価値が最 大になるものを選ぶC
  12. 12. ナップサック問題 価値 55 体積 40 価値 82 体積 97 価値 38 体積 19 価値 63 体積 32 価値 61 体積 26 容積 150 合計:価値 0 体積 0
  13. 13. ナップサック問題 価値 55 体積 40 価値 82 体積 97 価値 38 体積 19 価値 63 体積 32 価値 61 体積 26 容積 150 合計:価値 55 体積 40
  14. 14. ナップサック問題 価値 55 体積 40 価値 82 体積 97 価値 38 体積 19 価値 63 体積 32 価値 61 体積 26 容積 150 合計:価値 61 体積 26
  15. 15. ナップサック問題 価値 55 体積 40 価値 82 体積 97 価値 38 体積 19 価値 63 体積 32 価値 61 体積 26 容積 150 合計:価値 116 体積 66
  16. 16. ナップサック問題 価値 55 体積 40 価値 82 体積 97 価値 38 体積 19 価値 63 体積 32 価値 61 体積 26 容積 150 合計:価値 82 体積 97
  17. 17. ナップサック問題 価値 55 体積 40 価値 82 体積 97 価値 38 体積 19 価値 63 体積 32 価値 61 体積 26 容積 150 合計:価値 137 体積 137
  18. 18. ナップサック問題 価値 55 体積 40 価値 82 体積 97 価値 38 体積 19 価値 63 体積 32 価値 61 体積 26 容積 150 合計:価値 143 体積 133
  19. 19. ナップサック問題 価値 55 体積 40 価値 82 体積 97 価値 38 体積 19 価値 63 体積 32 価値 61 体積 26 容積 150 合計:価値 198 体積 173
  20. 20. ナップサック問題 価値 55 体積 40 価値 82 体積 97 価値 38 体積 19 価値 63 体積 32 価値 61 体積 26 容積 150 合計:価値 217 体積 117
  21. 21. ナップサック問題 ●ナイーブ(ばか正直)な解法 ●実装としては次のようにすると簡潔になる・多少高 速化する ●http://inside/~prime/procon/2014/normal/napsac.cpp ●ナップサックの空きと今何番目の荷物を見ている か、荷物の配列を引数に取る
  22. 22. ナップサック問題 ●ナイーブ(ばか正直)な解法 ● 個の荷物があるとき、調べるのは 通り ●問題の条件は だった ●    だとだいたい     年かかる n 2n 3.4×10285 n=1000 1≤n≤1,000 1≤Pi≤1,000,000,000 1≤V i≤1,000 1≤C≤1,000
  23. 23. ナップサック問題 ●ここで動的計画法を使う ●荷物 を見ていて残り容積が の時の価値の最 大値を記憶しておけば良い ●   になり、問題の条件でも時間内に解ける ●実際のコード ●http://inside/~prime/procon/2014/normal/napsac_dp.cpp i v O(nV )
  24. 24. ナップサック問題 ●動的計画法で解くイメージ vi 0 1 2 3 0 0 1 0 2 0 3 0 4 0 5 0 価値 2 体積 2 価値 5 体積 3 価値 3 体積 1
  25. 25. ナップサック問題 ●動的計画法で解くイメージ vi 0 1 2 3 0 0 0 1 0 2 0 3 0 4 0 5 0 価値 2 体積 2 価値 5 体積 3 価値 3 体積 1
  26. 26. ナップサック問題 ●動的計画法で解くイメージ vi 0 1 2 3 0 0 0 1 0 0 2 0 3 0 4 0 5 0 価値 2 体積 2 価値 5 体積 3 価値 3 体積 1
  27. 27. ナップサック問題 ●動的計画法で解くイメージ vi 0 1 2 3 0 0 0 1 0 0 2 0 2 3 0 4 0 5 0 価値 2 体積 2 価値 5 体積 3 価値 3 体積 1
  28. 28. ナップサック問題 ●動的計画法で解くイメージ vi 0 1 2 3 0 0 0 1 0 0 2 0 2 3 0 2 4 0 2 5 0 2 価値 2 体積 2 価値 5 体積 3 価値 3 体積 1
  29. 29. ナップサック問題 ●動的計画法で解くイメージ vi 0 1 2 3 0 0 0 0 1 0 0 0 2 0 2 2 3 0 2 5 4 0 2 5 5 0 2 7 価値 2 体積 2 価値 5 体積 3 価値 3 体積 1
  30. 30. ナップサック問題 ●動的計画法で解くイメージ vi 0 1 2 3 0 0 0 0 1 0 0 0 2 0 2 2 3 0 2 5 4 0 2 5 5 0 2 7 価値 2 体積 2 価値 5 体積 3 価値 3 体積 1
  31. 31. ナップサック問題 ●動的計画法で解くイメージ vi 0 1 2 3 0 0 0 0 0 1 0 0 0 3 2 0 2 2 3 3 0 2 5 5 4 0 2 5 8 5 0 2 7 8 価値 2 体積 2 価値 5 体積 3 価値 3 体積 1
  32. 32. ナップサック問題 ●動的計画法で解くイメージ vi 0 1 2 3 0 0 0 0 0 1 0 0 0 3 2 0 2 2 3 3 0 2 5 5 4 0 2 5 8 5 0 2 7 8 価値 2 体積 2 価値 5 体積 3 価値 3 体積 1
  33. 33. 補足 ●ナップサック問題であればいつでも動的計画法 を使うわけではない ●条件が のとき、動的計画法では解けないが、ナイーブな解 法を使えば解ける ●条件をよく読んで使い分ける 1≤n≤20 1≤Pi≤1,000,000,000 1≤V i≤1,000,000,000 1≤C≤1,000,000,000
  34. 34. 参考文献 ●プログラミングコンテストでの動的計画法 ●http://www.slideshare.net/iwiwi/ss-3578511

×