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
15年続くIoTサービスのSREエンジニアが挑む分散トレーシング導入
melonps
2
170
AI Agent の開発と運用を支える Durable Execution #AgentsInProd
izumin5210
7
2.3k
なるべく楽してバックエンドに型をつけたい!(楽とは言ってない)
hibiki_cube
0
140
React 19でつくる「気持ちいいUI」- 楽観的UIのすすめ
himorishige
11
5.9k
Rust 製のコードエディタ “Zed” を使ってみた
nearme_tech
PRO
0
140
HTTPプロトコル正しく理解していますか? 〜かわいい猫と共に学ぼう。ฅ^•ω•^ฅ ニャ〜
hekuchan
2
680
メルカリのリーダビリティチームが取り組む、AI時代のスケーラブルな品質文化
cloverrose
2
510
フロントエンド開発の勘所 -複数事業を経験して見えた判断軸の違い-
heimusu
7
2.8k
16年目のピクシブ百科事典を支える最新の技術基盤 / The Modern Tech Stack Powering Pixiv Encyclopedia in its 16th Year
ahuglajbclajep
5
990
AgentCoreとHuman in the Loop
har1101
5
220
SourceGeneratorのススメ
htkym
0
190
AI Agent Tool のためのバックエンドアーキテクチャを考える #encraft
izumin5210
6
1.8k
Featured
See All Featured
Context Engineering - Making Every Token Count
addyosmani
9
650
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
Agile that works and the tools we love
rasmusluckow
331
21k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
1
120
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.7k
Making Projects Easy
brettharned
120
6.6k
A designer walks into a library…
pauljervisheath
210
24k
Building AI with AI
inesmontani
PRO
1
680
Principles of Awesome APIs and How to Build Them.
keavy
128
17k
GraphQLとの向き合い方2022年版
quramy
50
14k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
440
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
320
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