- ๊ณจ๋ ๋๋น ์ฝ๋ฉ ํ ์คํธ ํฉ๊ฒฉ์ ๋๊ธฐ ํ์ด์ฌ ํธ์ 15์ฅ ์จ๋จธ๋ฆฌ๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
- ๋์ ๊ณํ๋ฒ์ ๋ชจ๋ ๋ฌธ์ ๋ฅผ ๋ค ํ์ง ๋ชปํ๋ค. ์ด๋ ต๊ธฐ๋ ํ์ง๋ง, DP์ ์ ์๋ ค์ง ์ฐ์ต ๋ฌธ์ ์ ์ต์ํด ์ง๋ ๊ฒ์ด ๋ชฉํ์ด๋ค.
๋์ ๊ณํ๋ฒ ๋ฌธ์ ์กฐ๊ฑด
์ต์ ๋ถ๋ถ ๊ตฌ์กฐ(Optimal substructure) ํฐ ๋ฌธ์ ์ ํด๊ฒฐ์ฑ ์ ์์ ๋ฌธ์ ์ ํด๊ฒฐ์ฑ ์ ํฉ์ผ๋ก ๊ตฌ์ฑํ ์ ์์ด์ผ ํ๋ค.
๊ตฌํ ๋ฐฉ๋ฒ : ์ ํ์ ์ธ์ฐ๊ธฐ์ค๋ณต ๋ถ๋ถ ๋ฌธ์ (Overlapping subproblems) ์์ ๋ฌธ์ ๋ค์ด ๊ฐ์์ผ ํ๊ณ ๋ฐ๋ณต๋์ด์ผ ํ๋ค. ๊ตฌํ ๋ฐฉ๋ฒ : ๋ฉ๋ชจ์ด์ ์ด์ ์ ํตํด ๋ฐ๋ณต๋๋ ์์ ๋ฌธ์ ์ ์ฐ์ฐ ํ์๋ฅผ ์ค์ฌ ์ฐ์ฐ ํจ์จํ ์ฆ๋.
๋ฌธ์ ์ ์ฉ
LIS๊ธธ์ด ๊ณ์ฐํ๊ธฐ
๋ฌธ์ ์ค๋ช ์ ์ ๋ฐฐ์ด nums์์ LIS์ ๊ธธ์ด๋ฅผ ์ฐพ๋ ํจ์๋ฅผ ์์ฑํ์ธ์. nums์ ์ต๋ ๊ธธ์ด 1,000์ ์ ์ ๋ฐฐ์ด nums์ ๊ฐ ์์๋ -1000 ์ด์ 1000์ดํ์ ์ ์ ์ ๋๋ค. ์ ๋ ฅ [1,4,2,3,1,5,7,3], 5 [3,2,1] 1
LIS(Longest Increasing Subsequence) ๋ ์ต์ฅ ์ฆ๊ฐ ๋ถ๋ถ ์์ด๋ก์ ์ฃผ์ด์ง ์์ด์์ ๋ง๋ค์ ์๋ ๋ชจ๋ ๋ถ๋ถ ์์ด์์ ๊ฐ์ฅ ๊ธด ์ฆ๊ฐํ๋ ์์ด์ ๊ตฌํ๋ค. ์ฆ๊ฐํ๋ ๋ถ๋ถ ์์ด์ ๊ตฌํ ๋ ์ ํ ๊ด๊ณ๋ฅผ ์ ์ง ํด์ผ ํ๋ค.
1 4 2 3 1 5 7 3 ์์
์ ํ ๊ด๊ณ๋ฅผ ์ ์งํ ์์ด
1 2 3 5
์ ํ ๊ด๊ณ๋ฅผ ์ ์งํ์ง ์์ ์์ด
1 3 2 5 (์ธ๋ฑ์ค์ ์ ํ ์์๋ฅผ ๋ฐ๊พธ๋ฉด ์๋๋ค)
์ด ๋ฌธ์ ๋ฅผ brute force๋ก ์ ๊ทผ ํ ๊ฒฝ์ฐ, 1๋ก ๋๋๋ ๋ถ๋ถ์์ด, 4๋ก ๋๋๋ ๋ถ๋ถ์์ด, 2์ผ๋ก ๋๋๋ ๋ถ๋ถ์์ด,... 3๋ก ๋๋๋ ๋ถ๋ถ ์์ด์์ ์ฆ๊ฐํ๋ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์ต๋ ๊ธธ์ด๋ฅผ ๊ตฌํ๊ฒ ๋ ๊ฒ ์ด๋ค. ์๊ฐ๋ณต์ก๋๋ 2^1000 ์ด ๋๋ฏ๋ก ์ฐ์ฐ์ ์ต์ ํ๊ฐ ํ์ํ๋ค.
1 4 2 3 ์์
[1] 1๋ก ๋๋๋ LIS๊ธธ์ด
[1,4] 4๋ก ๋๋๋ LIS๊ธธ์ด
[1,4,2] 2๋ก ๋๋๋ LIS๊ธธ์ด
[1,4,2,3,] 3๋ก ๋๋๋ LIS๊ธธ์ด
์ต์ ๋ถ๋ถ ๊ตฌ์กฐ : ๊ฐ ์ซ์๋ก ๋๋๋ LIS๊ธธ์ด ์ค ์ต๋๊ฐ (์ฌ๊ธฐ์ ๊ฐ ์ซ์๋ ๊ฐ์ฅ ์์ ๊ธธ์ด 1 ์ ์์์ผ ํ๋ค.)
์ค๋ณต ๋ถ๋ถ ๋ฌธ์ : 2๋ก ๋๋๋ LIS์ ๊ธธ์ด๋ฅผ ๊ตฌํ ๋, 4๋ก ๋๋๋ LIS ๊ธธ์ด๋ฅผ ์ฐธ์กฐํ๋ค.
๋ฌธ์ ์์ ๊ตฌํ๊ณ ์ ํ๋๊ฒ dp[N]: arr[N]์ด ๋ง์ง๋ง ์ซ์๋ก ๋๋๋ LIS์ ๊ธธ์ด.
dp์ ์ ํ์ ์ DP[N] = max(dp[k] )+1 ์ด ๋๊ณ ์ฌ๊ธฐ์ ์กฐ๊ฑด์ `arr[k]<arr[N]` ์ด ๋๋ค.
k: 0~ N-1 , N ์ด์ ์ ์ซ์๋ฅผ ๋ณด๋ ํฌ์ธํฐ
์ข
๋ฃ ์กฐ๊ฑด :
dp[1] =1 //๊ธธ์ด๊ฐ 1์ผ ๋, ๊ฐ์ฅ ๊ธด ์ฆ๊ฐํ๋ ์์ด์ ๊ธธ์ด๋ 1๊ฐ์ด๋ค.
//์๊ฐ ๋ณต์ก๋ : O(n^2)
function solution(nums){
let dp = Array.from({length: nums.length+1}, ()=> 1)
for (let i=0; i<nums.length; i++){
for(let j=0; j<i;j++){
if(nums[i]>nums[j]){
dp[i] = Math.max(dp[i], dp[j]+1)
}
}
}
return Math.max(...dp)
}
LCS ๊ธธ์ด ๊ณ์ฐํ๊ธฐ
๋ฌธ์ ํ์ด ์ฃผ์ด์ง ๋ ๊ฐ์ ๋ฌธ์์ด str1๊ณผ str2์ ๋ํด ์ต์ฅ ๊ณตํต ๋ถ๋ถ ์์ด์ ๊ธธ์ด๋ฅผ ๊ณ์ฐํ๋ solution() ํจ์๋ฅผ ๊ตฌํํ์ธ์.
์ ์ฝ ์กฐ๊ฑด
- ๊ฐ ๋ฌธ์์ด str1๊ณผ str2์ ๊ธธ์ด๋ 1 ์ด์ 1,000์ดํ ์ ๋๋ค.
- ๋ฌธ์์ด์ ์ํ๋ฒณ ๋๋ฌธ์, ์๋ฌธ์๋ก ๊ตฌ์ฑ ๋์ด ์์ต๋๋ค.
LCS(Longest Common Subsequence) ๋ ๋ ์์ด์์ ๊ณตํต์ผ๋ก ๋ฐ๊ฒฌํ ์ ์๋ ๊ฐ์ฅ ๊ธด ๋ถ๋ถ ์์ด์ ์๋ฏธํ๋ค.
๋ ๊ฐ์ ๋ฌธ์์ด์ ์ธ๋ฑ์ค๋ฅผ ํ๋์ฉ ๋น๊ตํด ๋ด์ผ ํ๋ค.
๋ฌธ์ ์์ ๊ตฌํ๊ณ ์ ํ๋๊ฒ
dp[i][j]: ์ฒซ ๋ฌธ์์ด์ ์ธ๋ฑ์ค 0~ i๋ฒ์งธ๊น์ง์ ๋ฌธ์์ด๊ณผ ๋๋ฒ์งธ ๋ฌธ์์ด ์ธ๋ฑ์ค 0~j๋ฒ์งธ ๊น์ง์ ๋ฌธ์์ด์ ๋น๊ตํ์ ๋,๊ณตํต ๋ถ๋ถ ๋ฌธ์์ด์ ์ต๋ ๊ธธ์ด
์ ํ์
dp[i][j] = dp[i-1][j-1]+1 if str1[i] === str2[j]
dp[i][j] = dp[i-1,j][i,j-1] if str1[i] !== str2[j]
dp[0][0] = 0
// ์๊ฐ๋ณต์ก๋: O(str1.length*str2.length)
ํผ๋ณด๋์น ์ ๋ฌธ์ ์ถ์ฒ: ํ๋ก๊ทธ๋๋จธ์ค
๋ฌธ์ ์ค๋ช ํผ๋ณด๋์น ์๋ F(0) = 0, F(1) = 1์ผ ๋, 1 ์ด์์ n์ ๋ํ์ฌ F(n) = F(n-1) + F(n-2) ๊ฐ ์ ์ฉ๋๋ ์ ์ ๋๋ค.
์๋ฅผ๋ค์ด
F(2) = F(0) + F(1) = 0 + 1 = 1 F(3) = F(1) + F(2) = 1 + 1 = 2 F(4) = F(2) + F(3) = 1 + 2 = 3 F(5) = F(3) + F(4) = 2 + 3 = 5 ์ ๊ฐ์ด ์ด์ด์ง๋๋ค.
2 ์ด์์ n์ด ์ ๋ ฅ๋์์ ๋, n๋ฒ์งธ ํผ๋ณด๋์น ์๋ฅผ >1234567์ผ๋ก ๋๋ ๋๋จธ์ง๋ฅผ ๋ฆฌํดํ๋ ํจ์, solution์> ์์ฑํด ์ฃผ์ธ์.
์ ํ ์ฌํญ n์ 2 ์ด์ 100,000 ์ดํ์ธ ์์ฐ์์ ๋๋ค.
์ ๋ ฅ๊ฐ์ด ์ญ๋ง์ด๋ O(n)์ ๋ณต์ก๋๋ ๊ฐ๋ฅํ๋ค.
ํผ๋ณด๋์น์ ์์์ ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ๋ F(n)์ ๊ตฌํ๊ธฐ ์ํด ์ด๋ฏธ ๊ณ์ฐ ๋์ด์ง ๋ฐ๋ก ์์ ๋ ํญ์ ๊ฐ ๊ฒฐ๊ณผ ๊ฐ,F(n-1), F(n-2)์ด๋ค. ๊ฒฐ๊ณผ ๊ฐ๋ค์ ๊ตฌํด์ผ ํฐ ๊ฐ์ธ F(n)์ ๊ตฌํ ์ ์๋ค.
๋ง์ฝ ์ด ๋ฌธ์ ๋ฅผ ์ฌ๊ท๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค๋ฉด, F(4)=F(3)+F(2) ์ผ ๋ F(3) ์ ๊ณ์ฐ์ F(2) +F(1) ์์ F(2)๋ฅผ ์ค๋ณต์ผ๋ก ๊ณ์ฐํ๋ ๋ถ๋ถ์ ๋ฉ๋ชจ์ด์ ์ด์ ์ ํตํด ์ต์ ํ ํ ์ ์์ผ๋ฏ๋ก,์ค๋ณต ๋ถ๋ถ ๋ฌธ์ ์ ํด๋น ๋๋ค.
์๋๋ ๋ฉ๋ชจ์ด์ ์ด์ ์ ๋ฐํ ์ ๋ฐฉ์์ ์ ์ฉํ์๋ค.
function solution(n) {
if(n<2) return 1%1234567
let a=0, b=1
let remainder;
for(let i=2; i<=n; i++){
remainder = (a+ b)%1234567
a = b
b = remainder
}
return b;
}
2 x n ํ์ผ๋ง ๋ฌธ์ ์ถ์ฒ: ํ๋ก๊ทธ๋๋จธ์ค
๋ฌธ์ ์ค๋ช ๋ฌธ์ ์ค๋ช ๊ฐ๋ก ๊ธธ์ด๊ฐ 2์ด๊ณ ์ธ๋ก์ ๊ธธ์ด๊ฐ 1์ธ ์ง์ฌ๊ฐํ๋ชจ์์ ํ์ผ์ด ์์ต๋๋ค. ์ด ์ง์ฌ๊ฐํ ํ์ผ์ ์ด์ฉํ์ฌ ์ธ๋ก์ ๊ธธ์ด๊ฐ 2์ด๊ณ ๊ฐ๋ก์ ๊ธธ์ด๊ฐ n์ธ ๋ฐ๋ฅ์ ๊ฐ๋ ์ฑ์ฐ๋ ค๊ณ ํฉ๋๋ค. ํ์ผ์ ์ฑ์ธ ๋๋ ๋ค์๊ณผ ๊ฐ์ด 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
ํ์ผ์ ๊ฐ๋ก๋ก ๋ฐฐ์น ํ๋ ๊ฒฝ์ฐ ํ์ผ์ ์ธ๋ก๋ก ๋ฐฐ์น ํ๋ ๊ฒฝ์ฐ ์๋ฅผ๋ค์ด์ n์ด 7์ธ ์ง์ฌ๊ฐํ์ ๋ค์๊ณผ ๊ฐ์ด ์ฑ์ธ ์ ์์ต๋๋ค.
์ง์ฌ๊ฐํ์ ๊ฐ๋ก์ ๊ธธ์ด n์ด ๋งค๊ฐ๋ณ์๋ก ์ฃผ์ด์ง ๋, ์ด ์ง์ฌ๊ฐํ์ ์ฑ์ฐ๋ ๋ฐฉ๋ฒ์ ์๋ฅผ return ํ๋ solution ํจ์๋ฅผ ์์ฑํด์ฃผ์ธ์.
์ ํ์ฌํญ ๊ฐ๋ก์ ๊ธธ์ด n์ 60,000์ดํ์ ์์ฐ์ ์ ๋๋ค. ๊ฒฝ์ฐ์ ์๊ฐ ๋ง์ ์ง ์ ์์ผ๋ฏ๋ก, ๊ฒฝ์ฐ์ ์๋ฅผ 1,000,000,007์ผ๋ก ๋๋ ๋๋จธ์ง๋ฅผ returnํด์ฃผ์ธ์. ์ ์ถ๋ ฅ ์ n result 4 5
์ด ๋ฌธ์ ๊ฐ DP์ธ ์ด์ ๋
- ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ
n = 3์ n = 1์ผ ๋ ๊ฒฝ์ฐ์ ์์ n=2์ผ ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ทธ๋๋ก ์ด์ฉํ๋ค. ์ธ๋ก๊ธธ์ด๋ ์ ํด์ ธ ์๊ณ , ์ฃผ์ด์ง ํ์ผ์ ๊ฐ๋ก ๊ธธ์ด๋ 1๋๋ 2 ์ด๋ฏ๋ก ๊ฐ๋ก ๊ธธ์ด๊ฐ 1์ผ ๋์ 2์ผ ๋ ๊ฒฝ์ฐ์ ์๊ฐ ๋ฌ๋ผ์ง๋ค. ๊ทธ๋ผ ๋ง์ง๋ง์ ์ฌ ํ์ผ์ด ๊ฐ๋ก๊ธธ์ด 1์ธ ํ์ผ๊ณผ 2์ธ ํ์ผ ๋ ๊ฐ๋ก ๊ฒฐ์ ์ง์ด ์ง๋ฏ๋ก, n-1 ๊ฒฝ์ฐ์ ์ , n-2 ๊ฒฝ์ฐ์ ์ ํฉ์ผ๋ก ๋ํ๋ผ ์ ์๋ค. n =3์ ํ๊ธฐ ์ํด์ , n =2 ๊ฒฝ์์ ์์ n=1์ผ๋์ ๊ฐ์ง์์ ์์กดํ๋ค.
- ์ค๋ณต ๋ถ๋ถ ๋ฌธ์ ์ ํ์์ผ๋ก ๋ํ๋ด๋ฉด dp[n] = dp[n-1]+dp[n-2] ๊ฐ ๋๊ณ , ์ ํ์์ ์ฌ๊ท ์ฐ์ฐ์ ์ฌ์ฉํ๊ฒ ๋๋ฉด, ํผ๋ณด๋์น์์ด์ ์ฌ๊ท๋ก ํํํ ๋ฐฉ์ ์ฒ๋ผ ๊ฐ์ ์ฐ์ฐ์ ๋ฐ๋ณตํ๋ ์ผ์ด ์๊ธฐ๋ฏ๋ก ๋ฉ๋ชจ์ด์ ์ด์ ์ ์ฌ์ฉํ๋ค. ์กฐ๊ฑด์ ๋ง์กฑํ๊ธฐ ๋๋ฌธ์ด๋ค.
function solution(n) {
let dp = Array.from({length: n+1},()=>0);
dp[1] = 1;
dp[2] = 2;
if(n <= 2 ) return dp[n];
for(let i=3; i<=n; i++){
dp[i] = (dp[i-1] + dp[i-2])%1000000007;
}
return dp[n]
}
์ ์ ์ผ๊ฐํ (๋ฌธ์ ์ถ์ฒ: ํ๋ก๊ทธ๋๋จธ์ค)[]
์์ ๊ฐ์ ์ผ๊ฐํ์ ๊ผญ๋๊ธฐ์์ ๋ฐ๋ฅ๊น์ง ์ด์ด์ง๋ ๊ฒฝ๋ก ์ค, ๊ฑฐ์ณ๊ฐ ์ซ์์ ํฉ์ด ๊ฐ์ฅ ํฐ ๊ฒฝ์ฐ๋ฅผ ์ฐพ์๋ณด๋ ค๊ณ ํฉ๋๋ค. ์๋ ์นธ์ผ๋ก ์ด๋ํ ๋๋ ๋๊ฐ์ ๋ฐฉํฅ์ผ๋ก ํ ์นธ ์ค๋ฅธ์ชฝ ๋๋ ์ผ์ชฝ์ผ๋ก๋ง ์ด๋ ๊ฐ๋ฅํฉ๋๋ค. ์๋ฅผ ๋ค์ด 3์์๋ ๊ทธ ์๋์นธ์ 8 ๋๋ 1๋ก๋ง ์ด๋์ด ๊ฐ๋ฅํฉ๋๋ค.
์ผ๊ฐํ์ ์ ๋ณด๊ฐ ๋ด๊ธด ๋ฐฐ์ด triangle์ด ๋งค๊ฐ๋ณ์๋ก ์ฃผ์ด์ง ๋, ๊ฑฐ์ณ๊ฐ ์ซ์์ ์ต๋๊ฐ์ return ํ๋๋ก solution ํจ์๋ฅผ ์์ฑํ์ธ์.
์ ํ์ฌํญ ์ผ๊ฐํ์ ๋์ด๋ 1 ์ด์ 500 ์ดํ์ ๋๋ค. ์ผ๊ฐํ์ ์ด๋ฃจ๊ณ ์๋ ์ซ์๋ 0 ์ด์ 9,999 ์ดํ์ ์ ์์ ๋๋ค.
์ ์ถ๋ ฅ ์ triangle result [[7], [3, 8], [8, 1, 0], [2, 7, 4, 4], [4, 5, 2, 6, 5]] 30
๋ฌธ์ ์์ ๊ตฌํ๊ณ ์ ํ๋ ๊ฒ์ ์ผ๊ฐํ์ ๊ผญ๋๊ธฐ์์ ๋ฐ๋ฅ๊น์ง ๊ฑฐ์น๋ ์ซ์๋ค์ ํฉ ์ค ๊ฐ์ฅ ํฐ ์ต๋๊ฐ์ ๊ตฌํ๋ค.
์ด ๋ฌธ์ ๋ฅผ brute force๋ฐฉ์์ผ๋ก ํ๊ฒ ๋๋ฉด ๊ผญ๋๊ธฐ 7->3 ์ผ๋ก ์์ํ์ฌ ๋์ฐฉํ๋ ๋ชจ๋ ๊ฒฝ์ฐ์ ์, 7->8 ๋ก ์์ํ์ฌ ๋์ฐฉํ๋ ๋ชจ๋ ๊ฒฝ์ฐ์ ์์์ ํฉ์ ์ฐพ์๋ด์ด ๊ทธ ์ค์ ์ต๋๊ฐ์ ๊ตฌํ๋ ๋ฐฉ์์ผ๋ก ์ ๊ทผํ๋ค, ํ์ง๋ง, ๋์ด๊ฐ 500์ผ ๋ ๊ฒฝ์ฐ์ ์๋ ๋์ด๊ฐ 1์ผ ๋ ๊ฒฝ์ฐ์ ์ 1, ๋์ด๊ฐ 2์ผ ๋ ๊ฒฝ์ฐ์ ์ 2, ๋์ด๊ฐ 3์ผ ๋ ๊ฒฝ์ฐ์ ์ 4 , 2^(๋์ด) ๋ก 2^500 ์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๊ฒ ๋๋ค. ์ด๋ฅผ ํตํด DP๋ก ์ฐ์ฐ์ ์ต์ ํ ํด์ผ ํ๋ค.
๋ฐ๋ฅ์ ๋์ฐฉํ์ ๋ [4, 5, 2, 6, 5]
์ ๋ฐ๋ผ 4๋ก ๋์ฐฉํ๋ ๊ฒฝ์ฐ, 5๋ก ๋์ฐฉํ๋ ๊ฒฝ์ฐ, 6๋ก ๋์ฐฉํ๋ ๊ฒฝ์ฐ, 5๋ก ๋์ฐฉํ๋ ๊ฒฝ์ฐ์์ ์ต๋๊ฐ์ด ๊ผญ๋๊ธฐ๋ถํฐ ๋ฐ๋ฅ๊น์ง ๊ฑฐ์น๋ ์ซ์๋ค์ ์ต๋๊ฐ์ด ๋๋ค.
๋ฐ๋ฅ์ 4๋ ๊ทธ ์ ๋จ๊ณ์ ํฉ์ ์์กดํ๊ฒ ๋๋ฏ๋ก, ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ์ ๋ง์กฑํ๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฒฝ๋ก์์ ๋์ฐฉํ๋ ์ง์ ์๋ ๊ธฐ์ตํด๋ ๊ทธ ์ ๋จ๊ณ์ ํฉ์ ๊ฐ์ ธ์ ๋์ฐฉ์ง์ ์ ํฉ์ฐํ๋ค๋ ์ ์์ ์ค๋ณต ๋ถ๋ถ ๋ฌธ์ ์ ํฌํจ๋๋ค.
function solution(triangle) {
for (let row = triangle.length - 2; row >= 0; row--) {
for (let col = 0; col < triangle[row].length; col++) {
// ์๋์ชฝ ํ์ ์ธ์ ํ ๋ ์ซ์ ์ค ๋ ํฐ ์ซ์๋ฅผ ํ์ฌ ์ซ์์ ๋ํจ
triangle[row][col] += Math.max(triangle[row + 1][col], triangle[row + 1][col + 1]);
}
}
// ์ต์๋จ์ ์ต๋๊ฐ์ด ์กด์ฌํจ
return triangle[0][0];
}