Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dynamic Programming 1

Avatar for Suikaba Suikaba
October 09, 2019

Dynamic Programming 1

動的計画法入門 その1

2019/10/09 に KCPC で発表した内容

Avatar for Suikaba

Suikaba

October 09, 2019
Tweet

Other Decks in Programming

Transcript

  1. ߟ͑ํ 1ɿܭࢉ݁ՌΛϝϞ͢Δ ྫ୊ɿϑΟϘφον਺ ϑΟϘφον਺ͷୈ n ߲ Fn ΛٻΊΑ • ͜ͷ໰୊Λ్தܭࢉΛϝϞԽͤͣʹղ͘ͱʜ

    • F5 ΛٻΊ͍ͨ • F5 = F3 + F4 ͔ͩΒ F3 Λܭࢉ͠Α͏ • F3 = F2 + F1 ͔ͩΒɺ͜Ε͸͙͢ʹ෼͔ͬͯ F3 = 2 3
  2. ߟ͑ํ 1ɿܭࢉ݁ՌΛϝϞ͢Δ ྫ୊ɿϑΟϘφον਺ ϑΟϘφον਺ͷୈ n ߲ Fn ΛٻΊΑ • ͜ͷ໰୊Λ్தܭࢉΛϝϞԽͤͣʹղ͘ͱʜ

    • F5 ΛٻΊ͍ͨ • F5 = F3 + F4 ͔ͩΒ F3 Λܭࢉ͠Α͏ • F3 = F2 + F1 ͔ͩΒɺ͜Ε͸͙͢ʹ෼͔ͬͯ F3 = 2 • F3 ͕ٻ·ͬͨͧʂ࣍͸ F4 ΛٻΊΑ͏ 3
  3. ߟ͑ํ 1ɿܭࢉ݁ՌΛϝϞ͢Δ ྫ୊ɿϑΟϘφον਺ ϑΟϘφον਺ͷୈ n ߲ Fn ΛٻΊΑ • ͜ͷ໰୊Λ్தܭࢉΛϝϞԽͤͣʹղ͘ͱʜ

    • F5 ΛٻΊ͍ͨ • F5 = F3 + F4 ͔ͩΒ F3 Λܭࢉ͠Α͏ • F3 = F2 + F1 ͔ͩΒɺ͜Ε͸͙͢ʹ෼͔ͬͯ F3 = 2 • F3 ͕ٻ·ͬͨͧʂ࣍͸ F4 ΛٻΊΑ͏ • F4 = F3 + F2 ͔ͩΒɺF3 Λܭࢉ͠ͳ͍ͱ 3
  4. ߟ͑ํ 1ɿܭࢉ݁ՌΛϝϞ͢Δ ྫ୊ɿϑΟϘφον਺ ϑΟϘφον਺ͷୈ n ߲ Fn ΛٻΊΑ • ͜ͷ໰୊Λ్தܭࢉΛϝϞԽͤͣʹղ͘ͱʜ

    • F5 ΛٻΊ͍ͨ • F5 = F3 + F4 ͔ͩΒ F3 Λܭࢉ͠Α͏ • F3 = F2 + F1 ͔ͩΒɺ͜Ε͸͙͢ʹ෼͔ͬͯ F3 = 2 • F3 ͕ٻ·ͬͨͧʂ࣍͸ F4 ΛٻΊΑ͏ • F4 = F3 + F2 ͔ͩΒɺF3 Λܭࢉ͠ͳ͍ͱ • F3 ͬͯͳΜ͚ͩͬɺ΋͔͍ͬܭࢉ͢Δ͔ʜ 3
  5. ߟ͑ํ 1ɿܭࢉ݁ՌΛϝϞ͢Δ ιʔείʔυ 1: ϝϞԽ͠ͳ͍ϑΟϘφον਺ͷܭࢉ 1 int fib(int n) {

    2 if(n == 1 || n == 2) return 1; 3 return fib(n - 1) + fib(n - 2); 4 } • ܭࢉྔ͸ O (( 1 + √ 5 2 )n ) 4
  6. ߟ͑ํ 1ɿܭࢉ݁ՌΛϝϞ͢Δ ιʔείʔυ 2: ϝϞԽͨ͠ϑΟϘφον਺ͷܭࢉ 1 // f[i] ͸͋Β͔͡Ί͢΂ͯ -1

    ͰॳظԽ͞Ε͍ͯΔͱ͢Δ 2 int fib(int n) { 3 if(n == 1 || n == 2) return 1; 4 if(f[n] != -1) { // աڈʹܭࢉͨ͜͠ͱ͕͋Δ 5 return f[n]; 6 } 7 f[n] = fib(n - 1) + fib(n - 2); 8 return f[n]; 9 } • ܭࢉྔ͸ O(n) 6
  7. ༗໊໰୊ɿφοϓαοΫ໰୊ φοϓαοΫ໰୊ n ݸͷՙ෺͕͋Δɻi ൪໨ͷՙ෺ͷॏ͞͸ wi Ͱ͋ΓɺՁ஋͸ vi Ͱ͋Δɻॏ͕͞ W

    Λ௒͑ͳ͍Α͏ʹՙ෺ΛબΜͩͱ͖ͷɺՁ஋ ͷ૯࿨Λ࠷େԽͤΑɻ • 1 ≤ n ≤ 103 • 1 ≤ wi ≤ 103 • 1 ≤ vi ≤ 106 • 1 ≤ W ≤ 103 8
  8. ༗໊໰୊ɿφοϓαοΫ໰୊ • DP ʹ׳Εͳ͍͏ͪ͸ɺ࠷ॳʹશ୳ࡧղΛߟ͑ΔͱΑ͍ ιʔείʔυ 4: φοϓαοΫ໰୊ʢશ୳ࡧղʣ 1 // ՙ෺

    i ʹ஫໨͍ͯͯ͠ɺ ͋ͱ W ͚ͩՙ෺Λ٧ΊΒΕΔ 2 int solve(int i, int W) { 3 if(i == n) return 0; 4 int res = 0; 5 if(W >= w[i]) { // i ൪໨ͷՙ෺Λ࢖͏ 6 res = solve(i + 1, W - w[i]) + v[i]; 7 } 8 // i ൪໨ͷՙ෺Λ࢖Θͳ͍ 9 res = max(res, solve(i + 1, W)); 10 return res; 11 } 9
  9. ༗໊໰୊ɿφοϓαοΫ໰୊ • ͜ͷ··ͩͱ O(2n) ͷܭࢉྔ • ֤ՙ෺ΛબͿબ͹ͳ͍ͷ 2 ௨Γ •

    ࣍ʹϝϞԽͰ͖ͳ͍͔ߟ͑Α͏ • solve(i, W) ͷҙຯΛߟ͑Δͱɺ͋Δ (i, W) ʹର͢Δܭࢉ݁ Ռ͸ৗʹಉ͡ • ϝϞԽ͕Ͱ͖Δʂ 10
  10. ༗໊໰୊ɿφοϓαοΫ໰୊ ιʔείʔυ 5: φοϓαοΫ໰୊ʢϝϞԽʣ 1 // ՙ෺ i ʹ஫໨͍ͯͯ͠ɺ ͋ͱ

    W ͚ͩՙ෺Λ٧ΊΒΕΔ 2 // dp[i][j] ͸࠷ॳ -1 ͰॳظԽ͞Ε͍ͯΔ 3 int solve(int i, int W) { 4 if(i == n) return 0; 5 if(dp[i][W] != -1) return dp[i][W]; 6 dp[i][W] = 0; 7 if(W >= w[i]) { // i ൪໨ͷՙ෺Λ࢖͏ 8 dp[i][W] = solve(i + 1, W - w[i]); 9 } 10 // i ൪໨ͷՙ෺Λ࢖Θͳ͍ 11 dp[i][W] = max(dp[i][W], solve(i + 1, W)); 12 return dp[i][W]; 13 } 11
  11. ༗໊໰୊ɿφοϓαοΫ໰୊ • ֤ (i, W) ʹରͯ͠ɺҰ౓ܭࢉͨ͠Β΋͏࠶ܭࢉ͸͞Εͳ͍ • ֤ (i, W)

    ʹ͍ͭͯɺؔ਺಺෦Ͱ͍ͯ͠Δܭࢉ͸ఆ਺ճ • Αͬͯܭࢉྔ͸શମͰ O(nW) • ͨͬͨ͜Ε͚ͩ௥Ճ͢Δ͚ͩͰɺܶతʹܭࢉྔ͕มΘΔ 12
  12. ߟ͑ํ 2ɿಉҰࢹͰ͖Δঢ়ଶΛ·ͱΊ্͛Δ • ͖ͬ͞ͷφοϓαοΫ໰୊Λ઴Խࣜతʹղ͍ͯΈΑ͏ • dp[i][j] := ՙ෺ 1, .

    . . , i ͔Βॏ͕͞ j ͱͳΔΑ͏ʹબΜͩͱ͖ ͷɺՁ஋ͷ࠷େ஋ • ઴ԽࣜͷભҠ͸ҎԼͷΑ͏ʹͳΔ dp[0][0] = 0 dp[i][j] = max{dp[i − 1][j], dp[i − 1][j − wi] + vi} 13
  13. ߟ͑ํ 2ɿಉҰࢹͰ͖Δঢ়ଶΛ·ͱΊ্͛Δ • Ͳ͏ͯ͜͠ΕͰߴ଎Խ͕Ͱ͖Δͷ͔ɺগ͠ҙຯΛߟ͑ͯΈΔ • dp[i][j] ͱ͸ՙ෺ 1, . .

    . , i ͔Βॏ͕͞ j ͱͳΔΑ͏ʹબΜͩঢ় ଶͰ͋Δ • ͜ͷΑ͏ͳબͼํ͸ɺෳ਺ଘࡏ͢ΔՄೳੑ͕͋Δ • w = 5 ͷͱ͖ʹɺॏ͞ 1, 4 ͷՙ෺ΛબΜͰ΋ྑ͍͠ɺॏ͞ 2, 3 ͷՙ෺ΛબΜͰ΋ྑ͍ • શ୳ࡧͱ͍͏ͷ͸ɺ͜ΕΒ͢΂ͯͷબͼํΛ۠ผͯ͠ߦ͏΋ͷ 14
  14. ߟ͑ํ 2ɿಉҰࢹͰ͖Δঢ়ଶΛ·ͱΊ্͛Δ • dp[i][j] Λ઴Խࣜతʹղ࣌͘ɺ͜ΕΒͷ۩ମతͳબͼํͷ৘ใ ͸མ͍ͪͯΔ • ॏཁͳͷ͸ɺॏ͞ͷ࿨ͱͦͷ࣌ͷՁ஋ (ͷ࠷େ஋) Ͱ͋ͬͯɺ

    ۩ମతͳબͼํͰ͸ͳ͍ͨΊɺ͜ͷΑ͏ͳ͜ͱ͕ڐ͞ΕΔ • ͜ͷΑ͏ʹɺDP Λߟ͑Δͱ͖ʹ͸ɺຊདྷ۠ผ͞Ε͍ͯͨঢ়ଶ Λ໰୊͕ղ͚ΔൣғͰ·ͱΊ্͛ɺঢ়ଶ਺Λখ͘͢͞Δ 15
  15. ࠓ೔ͷ·ͱΊ • DP ͱ͸ɺ໰୊ΛΑΓখ͍͞αΠζͷ෦෼໰୊ʹ෼ׂ͠ɺ్த ܭࢉΛه࿥͠ͳ͕ΒղΛٻΊΔख๏ • 2 ͭͷجຊతͳߟ͑ํ • ܭࢉ݁ՌͷϝϞԽ

    • ಉҰࢹՄೳͳঢ়ଶͷ·ͱΊ্͛Ͱঢ়ଶ਺Λ཈͑Δ • Ͳ͏͍͏ঢ়ଶΛ·ͱΊ্͛ΒΕΔ͔Λߟ͑Δ͜ͱ͕େ੾ • ٯʹݴ͑͹ɺམͱͯ͠͸ͳΒͳ͍৘ใ͸ͳʹ͔Λߟ͑Δ͜ͱ • ঢ়ଶ͸ɺDP ςʔϒϧͷఴࣈ΍࣋ͨͤΔ஋Ͱදݱ͢Δ 16