Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Dynamic Programming 1
Search
Suikaba
October 09, 2019
Programming
0
640
Dynamic Programming 1
動的計画法入門 その1
2019/10/09 に KCPC で発表した内容
Suikaba
October 09, 2019
Tweet
Share
Other Decks in Programming
See All in Programming
PHPカンファレンス関西2025 基調講演
sugimotokei
3
200
Claude Code + Container Use と Cursor で作る ローカル並列開発環境のススメ / ccc local dev
kaelaela
12
7.1k
PicoRuby on Rails
makicamel
3
140
『自分のデータだけ見せたい!』を叶える──Laravel × Casbin で複雑権限をスッキリ解きほぐす 25 分
akitotsukahara
2
660
ペアプロ × 生成AI 現場での実践と課題について / generative-ai-in-pair-programming
codmoninc
2
21k
Vibe Codingの幻想を超えて-生成AIを現場で使えるようにするまでの泥臭い話.ai
fumiyakume
15
6.3k
Azure AI Foundryではじめてのマルチエージェントワークフロー
seosoft
0
200
PipeCDのプラグイン化で目指すところ
warashi
1
310
ソフトウェア設計とAI技術の活用
masuda220
PRO
21
4.8k
AI駆動のマルチエージェントによる業務フロー自動化の設計と実践
h_okkah
0
230
AWS Summit Japan 2024と2025の比較/はじめてのKiro、今あなたは岐路に立つ
satoshi256kbyte
1
130
「テストは愚直&&網羅的に書くほどよい」という誤解 / Test Smarter, Not Harder
munetoshi
0
200
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
138
34k
We Have a Design System, Now What?
morganepeng
53
7.7k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Gamification - CAS2011
davidbonilla
81
5.4k
Designing Experiences People Love
moore
142
24k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.3k
Art, The Web, and Tiny UX
lynnandtonic
299
21k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Documentation Writing (for coders)
carmenintech
72
4.9k
Facilitating Awesome Meetings
lara
54
6.5k
Transcript
DP (Dynamic Programming, ಈతܭը๏) 1 KCPC div2 ߨ࠲ ˏ suibaka
2019/10/09 1
DP ͱͳʹ͔ • ΛΑΓʮখ͍͞αΠζͷ෦ʹׂʯ͠ɺͦΕΒ෦ Λղ͍ͨ݁ՌΛʮهʯ͠ͳ͕ΒܭࢉΛਐΊ͍ͯ͘ख๏ • ه͢Δ͜ͱΛϝϞԽͱ͍ͬͨΓ͢Δ • dijkstra ๏ͷΑ͏ʹɺܾ·ͬͨखଓ͖͕͋ΔΘ͚Ͱͳ͍
• ͔ͩΒ͍ͦ͜͠ 2
ߟ͑ํ 1ɿܭࢉ݁ՌΛϝϞ͢Δ ྫɿϑΟϘφον ϑΟϘφονͷୈ n ߲ Fn ΛٻΊΑ • ͜ͷΛ్தܭࢉΛϝϞԽͤͣʹղ͘ͱʜ
• F5 ΛٻΊ͍ͨ 3
ߟ͑ํ 1ɿܭࢉ݁ՌΛϝϞ͢Δ ྫɿϑΟϘφον ϑΟϘφονͷୈ n ߲ Fn ΛٻΊΑ • ͜ͷΛ్தܭࢉΛϝϞԽͤͣʹղ͘ͱʜ
• F5 ΛٻΊ͍ͨ • F5 = F3 + F4 ͔ͩΒ F3 Λܭࢉ͠Α͏ 3
ߟ͑ํ 1ɿܭࢉ݁ՌΛϝϞ͢Δ ྫɿϑΟϘφον ϑΟϘφονͷୈ n ߲ Fn ΛٻΊΑ • ͜ͷΛ్தܭࢉΛϝϞԽͤͣʹղ͘ͱʜ
• F5 ΛٻΊ͍ͨ • F5 = F3 + F4 ͔ͩΒ F3 Λܭࢉ͠Α͏ • F3 = F2 + F1 ͔ͩΒɺ͜Ε͙͢ʹ͔ͬͯ F3 = 2 3
ߟ͑ํ 1ɿܭࢉ݁ՌΛϝϞ͢Δ ྫɿϑΟϘφον ϑΟϘφονͷୈ n ߲ Fn ΛٻΊΑ • ͜ͷΛ్தܭࢉΛϝϞԽͤͣʹղ͘ͱʜ
• F5 ΛٻΊ͍ͨ • F5 = F3 + F4 ͔ͩΒ F3 Λܭࢉ͠Α͏ • F3 = F2 + F1 ͔ͩΒɺ͜Ε͙͢ʹ͔ͬͯ F3 = 2 • F3 ͕ٻ·ͬͨͧʂ࣍ F4 ΛٻΊΑ͏ 3
ߟ͑ํ 1ɿܭࢉ݁ՌΛϝϞ͢Δ ྫɿϑΟϘφον ϑΟϘφονͷୈ n ߲ Fn ΛٻΊΑ • ͜ͷΛ్தܭࢉΛϝϞԽͤͣʹղ͘ͱʜ
• F5 ΛٻΊ͍ͨ • F5 = F3 + F4 ͔ͩΒ F3 Λܭࢉ͠Α͏ • F3 = F2 + F1 ͔ͩΒɺ͜Ε͙͢ʹ͔ͬͯ F3 = 2 • F3 ͕ٻ·ͬͨͧʂ࣍ F4 ΛٻΊΑ͏ • F4 = F3 + F2 ͔ͩΒɺF3 Λܭࢉ͠ͳ͍ͱ 3
ߟ͑ํ 1ɿܭࢉ݁ՌΛϝϞ͢Δ ྫɿϑΟϘφον ϑΟϘφονͷୈ n ߲ Fn ΛٻΊΑ • ͜ͷΛ్தܭࢉΛϝϞԽͤͣʹղ͘ͱʜ
• F5 ΛٻΊ͍ͨ • F5 = F3 + F4 ͔ͩΒ F3 Λܭࢉ͠Α͏ • F3 = F2 + F1 ͔ͩΒɺ͜Ε͙͢ʹ͔ͬͯ F3 = 2 • F3 ͕ٻ·ͬͨͧʂ࣍ F4 ΛٻΊΑ͏ • F4 = F3 + F2 ͔ͩΒɺF3 Λܭࢉ͠ͳ͍ͱ • F3 ͬͯͳΜ͚ͩͬɺ͔͍ͬܭࢉ͢Δ͔ʜ 3
ߟ͑ํ 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
ߟ͑ํ 1ɿܭࢉ݁ՌΛϝϞ͢Δ • ಉ͡ n ʹର͢Δ Fn ͷ݁Ռಉ͡ • ໌Β͔ʹɺҰܭࢉͨ͠Β͏Ұܭࢉ͢Δඞཁͳ͍
• ͜Ε͕ϝϞԽͱ͍͏ߟ͑ํ • ؆୯Ͱ͠ΐ͏ʁ • ୯७ͳൃ͕ͩڧྗ 5
ߟ͑ํ 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
ิɿϝϞԽҎ֎ͷΓํ • ϝϞԽͱ͍͏ൃͰͳ͘ɺԽࣜతʹΔํ๏͋Δ • ͲͪΒΛ࠾༻͖͔͢ʹґଘ͢Δ • ܭࢉྔ͕มΘͬͯ͠·͏͜ͱ͕͋Δ • ܭࢉྔ͕ಉ͡ͰɺબʹΑ࣮͕ͬͯ؆୯ʹͳΔ͜ͱ ιʔείʔυ
3: ԽࣜతͳϑΟϘφονͷܭࢉ 1 f[1] = f[2] = 1; 2 for(int i = 3; i <= n; ++i) { 3 f[i] = f[i - 1] + f[i - 2]; 4 } 7
༗໊ɿφοϓαοΫ φοϓαοΫ n ݸͷՙ͕͋Δɻi ൪ͷՙͷॏ͞ wi Ͱ͋ΓɺՁ vi Ͱ͋Δɻॏ͕͞ W
Λ͑ͳ͍Α͏ʹՙΛબΜͩͱ͖ͷɺՁ ͷ૯Λ࠷େԽͤΑɻ • 1 ≤ n ≤ 103 • 1 ≤ wi ≤ 103 • 1 ≤ vi ≤ 106 • 1 ≤ W ≤ 103 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
༗໊ɿφοϓαοΫ • ͜ͷ··ͩͱ O(2n) ͷܭࢉྔ • ֤ՙΛબͿબͳ͍ͷ 2 ௨Γ •
࣍ʹϝϞԽͰ͖ͳ͍͔ߟ͑Α͏ • solve(i, W) ͷҙຯΛߟ͑Δͱɺ͋Δ (i, W) ʹର͢Δܭࢉ݁ Ռৗʹಉ͡ • ϝϞԽ͕Ͱ͖Δʂ 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
༗໊ɿφοϓαοΫ • ֤ (i, W) ʹରͯ͠ɺҰܭࢉͨ͠Β͏࠶ܭࢉ͞Εͳ͍ • ֤ (i, W)
ʹ͍ͭͯɺؔ෦Ͱ͍ͯ͠Δܭࢉఆճ • ΑͬͯܭࢉྔશମͰ O(nW) • ͨͬͨ͜Ε͚ͩՃ͢Δ͚ͩͰɺܶతʹܭࢉྔ͕มΘΔ 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
ߟ͑ํ 2ɿಉҰࢹͰ͖Δঢ়ଶΛ·ͱΊ্͛Δ • Ͳ͏ͯ͜͠ΕͰߴԽ͕Ͱ͖Δͷ͔ɺগ͠ҙຯΛߟ͑ͯΈΔ • dp[i][j] ͱՙ 1, . .
. , i ͔Βॏ͕͞ j ͱͳΔΑ͏ʹબΜͩঢ় ଶͰ͋Δ • ͜ͷΑ͏ͳબͼํɺෳଘࡏ͢ΔՄೳੑ͕͋Δ • w = 5 ͷͱ͖ʹɺॏ͞ 1, 4 ͷՙΛબΜͰྑ͍͠ɺॏ͞ 2, 3 ͷՙΛબΜͰྑ͍ • શ୳ࡧͱ͍͏ͷɺ͜ΕΒͯ͢ͷબͼํΛ۠ผͯ͠ߦ͏ͷ 14
ߟ͑ํ 2ɿಉҰࢹͰ͖Δঢ়ଶΛ·ͱΊ্͛Δ • dp[i][j] ΛԽࣜతʹղ࣌͘ɺ͜ΕΒͷ۩ମతͳબͼํͷใ མ͍ͪͯΔ • ॏཁͳͷɺॏ͞ͷͱͦͷ࣌ͷՁ (ͷ࠷େ) Ͱ͋ͬͯɺ
۩ମతͳબͼํͰͳ͍ͨΊɺ͜ͷΑ͏ͳ͜ͱ͕ڐ͞ΕΔ • ͜ͷΑ͏ʹɺDP Λߟ͑Δͱ͖ʹɺຊདྷ۠ผ͞Ε͍ͯͨঢ়ଶ Λ͕ղ͚ΔൣғͰ·ͱΊ্͛ɺঢ়ଶΛখ͘͢͞Δ 15
ࠓͷ·ͱΊ • DP ͱɺΛΑΓখ͍͞αΠζͷ෦ʹׂ͠ɺ్த ܭࢉΛه͠ͳ͕ΒղΛٻΊΔख๏ • 2 ͭͷجຊతͳߟ͑ํ • ܭࢉ݁ՌͷϝϞԽ
• ಉҰࢹՄೳͳঢ়ଶͷ·ͱΊ্͛Ͱঢ়ଶΛ͑Δ • Ͳ͏͍͏ঢ়ଶΛ·ͱΊ্͛ΒΕΔ͔Λߟ͑Δ͜ͱ͕େ • ٯʹݴ͑ɺམͱͯ͠ͳΒͳ͍ใͳʹ͔Λߟ͑Δ͜ͱ • ঢ়ଶɺDP ςʔϒϧͷఴࣈ࣋ͨͤΔͰදݱ͢Δ 16