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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Suikaba
October 09, 2019
Programming
0
650
Dynamic Programming 1
動的計画法入門 その1
2019/10/09 に KCPC で発表した内容
Suikaba
October 09, 2019
Tweet
Share
Other Decks in Programming
See All in Programming
Unicodeどうしてる? PHPから見たUnicode対応と他言語での対応についてのお伺い
youkidearitai
PRO
1
1.1k
AIによるイベントストーミング図からのコード生成 / AI-powered code generation from Event Storming diagrams
nrslib
2
1.8k
2026年 エンジニアリング自己学習法
yumechi
0
130
AI Schema Enrichment for your Oracle AI Database
thatjeffsmith
0
250
0→1 フロントエンド開発 Tips🚀 #レバテックMeetup
bengo4com
0
540
Vibe codingでおすすめの言語と開発手法
uyuki234
0
220
React 19でつくる「気持ちいいUI」- 楽観的UIのすすめ
himorishige
11
5.9k
AI時代の認知負荷との向き合い方
optfit
0
150
開発者から情シスまで - 多様なユーザー層に届けるAPI提供戦略 / Postman API Night Okinawa 2026 Winter
tasshi
0
200
[KNOTS 2026登壇資料]AIで拡張‧交差する プロダクト開発のプロセス および携わるメンバーの役割
hisatake
0
250
AI & Enginnering
codelynx
0
110
AIエージェントのキホンから学ぶ「エージェンティックコーディング」実践入門
masahiro_nishimi
4
310
Featured
See All Featured
For a Future-Friendly Web
brad_frost
182
10k
Mobile First: as difficult as doing things right
swwweet
225
10k
30 Presentation Tips
portentint
PRO
1
210
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
エンジニアに許された特別な時間の終わり
watany
106
230k
Designing Powerful Visuals for Engaging Learning
tmiket
0
220
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.3k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
55k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.9k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
180
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
0
3.4k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
1.8k
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