| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
- DP
- C++
- ML
- 항해99
- 코딩테스트
- 티스토리챌린지
- vue
- flutter getx
- 안드로이드
- 코테 파이썬
- 플러터
- 개발자취업
- 라라벨
- Flutter
- 파이썬 코테
- 뷰
- c++ 코테
- Python
- 백준
- 오블완
- til
- 코테
- 99클럽
- 파이썬
- 개발자 취업
- 코딩테스트준비
- 알고리즘
- 코딩테스트 준비
- react
- Laravel
- Today
- Total
잡다로그
[99클럽 코테 스터디] 8일차 TIL - 동적계획법, Pascal's Triangle 본문
[8일차] 동적계획법
문제: https://leetcode.com/problems/pascals-triangle/description/


* 대충 번역: 정수 numRows가 주어질 때, 파스칼의 삼각형의 첫 번째 numRows를 반환하라.
파스칼의 삼각형에서, 각 숫자는 위의 두 수의 합이다.
Solution
💡알고리즘 설계
위의 두 수를 더한 결과를 다음 계산에 재사용하게 되므로, 동적계획법(DP)를 활용할 수 있다.
1. DP 테이블 설계
D[i][k] = i번째 줄 k번째 원소의 값
2. 점화식 찾기
D[i][k] = D[i-1][k-1] + D[i-1][k]
3. 초기값 설정
D[0][0] = 1
D[i][0] = 1
D[i][i] = 1
class Solution(object):
def generate(self, numRows):
"""
:type numRows: int
:rtype: List[List[int]]
"""
d = []
for i in range(numRows): # dp 테이블 초기화
row = []
for k in range(i+1):
if k == i or k == 0:
row.append(1)
else:
row.append(0)
d.append(row)
for i in range(1, numRows): # 1부터 numRows-1까지
for k in range(1, i): # 1부터 i-1까지
d[i][k] = d[i-1][k-1] + d[i-1][k]
return d
인덱스를 활용하기 위해 dp테이블을 직접 초기화해줬다.
초기화와 값 대입(계산)을 한 번에 해줄 수도 있다.
class Solution(object):
def generate(self, numRows):
d = []
for i in range(numRows):
row = [1] * (i + 1)
for j in range(1, i):
row[j] = d[i - 1][j - 1] + d[i - 1][j]
d.append(row)
return d
Better Solution
나의 답은 다른 답 (예를 들어, 문자열, 변수 값, 등등)을 저장하는 문제에서는 유용할 수 있을 것 같다.
그러나 문제에서는 초기값이 1, 덧셈결과를 저장하는 조건이므로 초기화와 동시에 계산 값을 넣을 수 있고, 계산 또한 인덱스만으로 직접 dp테이블에 접근하지 않고도 계산이 가능하다. 왜냐하면 파스칼의 삼각형에는 이항계수 공식이 사용되기 때문이다.
class Solution(object):
def generate(self, numRows):
dp =[]
for i in range(1,numRows+1):
C=1 # dp[i][1] = 1
l=[]
for j in range(1,i+1):
l.append(C)
C = C * (i - j) // j
dp.append(l)
return dp
D[i][0] = 1, D[i][i] = 1 처럼 주어진 조건뿐만 아니라 D[i][1] = i 라는 조건도 도출해낼 수 있다.
풀이의 핵심이자 점화식으로도 볼 수 있는 C = C * (i - j) // j 는, dp[i][j+1] = dp[i][j] * (i - j) 와 같다.
이는 파스칼의 삼각형에서 각 항목은 이항계수를 사용하여 계산된다는 정의를 활용한 것이다.
이항계수 공식은 다음과 같고 n은 행 번호, k는 열 번호이다.

[알고리즘] DP - 이항계수 (Binomial coefficient)
목차 1. 이항계수의 정의 2. 이항계수 점화식 3. 파스칼의 삼각형 4. 이항계수 구현 정의 이항계수는 이항식을 이항정리로 전개했을 때 각 항의 계수를 나타냅니다. 이항식 $(x + y)^2$ 를 전개한 결
rh-tn.tistory.com
나다어
- 문제와 조건을 잘 살피자. 자주 쓰는 말이지만 어떤 답을 도출해야 하는지를 보면 문제 해결법이 나온다.. << 사실상 알고리즘의 핵심..^_ㅠ
- DP문제는 큰 값을 쪼개어 가는 Top-down 방식과, 작은 값에서 커지는 Bottom-up 방식이 있다.
- 문제에서 주어진 것이 단순 정수라면 직접 정답 배열에 접근하지 않고도 인덱스 자체를 값으로 활용할 수 있는지 생각해보자.
- 파이썬에서 배열에 원소를 추가하는 메소드는 push가 아닌 append이다.
Top-down DP와 Bottom-up DP의 차이점과 장단점, 쓰는 경우
Top-down DP와 Bottom-up DP DP를 푸는 방식에는 크게 두 가지 스타일이 있다고 할 수 있습니다. 첫 번째는, Top-down DP로, 큰 부분부터 작은 부분으로 쪼개지며 답을 찾습니다. 두 번째는 Bottom-up DP로, 작은
devruby7777.tistory.com
'Algorithm' 카테고리의 다른 글
| [99클럽 코테 스터디] 10일차 TIL - 동적계획법, Divisor Game (0) | 2024.06.09 |
|---|---|
| [99클럽 코테 스터디] 9일차 TIL - 동적계획법, Fibonacci Number (0) | 2024.06.08 |
| [99클럽 코테 스터디] 7일차 TIL - 동적계획법, Counting Bits (0) | 2024.06.06 |
| [Python/코테] 프로그래머스 구명보트 (0) | 2024.06.05 |
| [99클럽 코테 스터디] 6일차 TIL - 탐욕법(Greedy), Split a String in Balanced Strings (0) | 2024.06.05 |