1. 다리 놓기 - 1010
1010번: 다리 놓기
입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트케이스에 대해 강의 서쪽과 동쪽에 있는 사이트의 개수 정수 N, M (0 < N ≤ M < 30)이 주어진다.
www.acmicpc.net
1.0.1. 성능 요약
메모리: 31256 KB, 시간: 88 ms
1.0.2. 분류
조합론, 다이나믹 프로그래밍, 수학
1.0.3. 문제 설명
재원이는 한 도시의 시장이 되었다. 이 도시에는 도시를 동쪽과 서쪽으로 나누는 큰 일직선 모양의 강이 흐르고 있다. 하지만 재원이는 다리가 없어서 시민들이 강을 건너는데 큰 불편을 겪고 있음을 알고 다리를 짓기로 결심하였다. 강 주변에서 다리를 짓기에 적합한 곳을 사이트라고 한다. 재원이는 강 주변을 면밀히 조사해 본 결과 강의 서쪽에는 N개의 사이트가 있고 동쪽에는 M개의 사이트가 있다는 것을 알았다. (N ≤ M)
재원이는 서쪽의 사이트와 동쪽의 사이트를 다리로 연결하려고 한다. (이때 한 사이트에는 최대 한 개의 다리만 연결될 수 있다.) 재원이는 다리를 최대한 많이 지으려고 하기 때문에 서쪽의 사이트 개수만큼 (N개) 다리를 지으려고 한다. 다리끼리는 서로 겹쳐질 수 없다고 할 때 다리를 지을 수 있는 경우의 수를 구하는 프로그램을 작성하라.
1.0.4. 입력
입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트케이스에 대해 강의 서쪽과 동쪽에 있는 사이트의 개수 정수 N, M (0 < N ≤ M < 30)이 주어진다.
1.0.5. 출력
각 테스트 케이스에 대해 주어진 조건하에 다리를 지을 수 있는 경우의 수를 출력한다.
1.0.6. 문제 풀이
먼저 이 문제는 여러가지로 순열인 팩토리얼로 문제를 풀 수 있지만, 팩토리얼을 사용하는 것 보다, dp를 이용하는 것이 더 빠르다고 생각하여, 다이나믹 프로그래밍에서 Bottom-Up 방식으로 문제를 풀었습니다.
아래 글은 다이나믹 프로그래밍 Bottom-up에 대해 설명한 글입입니다.
한 번으로 코딩 역량을 향상하는 동적프로그래밍 기법을 알아보자! 🔥
동적프로그래밍은 처음 들어보는 사람들에게는 어려울 수 있지만, 실제로 코드를 작성해보면 그리 어렵지 않습니다. 아래 예제는 대표적인 동적프로그래밍 문제 중 하나인 피보나치 수열을 살
night-knight.tistory.com
참조
n m | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
2 | x | 1 | 3 | 6 | 10 | 15 | 21 |
3 | x | x | 1 | 4 | 10 | 20 | 35 |
4 | x | x | x | 1 | 5 | 15 | 35 |
5 | x | x | x | x | 1 | 6 | 21 |
표의 규칙성을 보면 (2,3) = (1,2) + (2+2)
점화식으로는 (i,j) = (i-1,j-1) + (i,j-1)
1.0.6.1.
1.0.6.2.
1.0.6.3.
1.0.6.4. 점화식를 바탕으로 DP bottom-up 을 사용하여 풀이
1.0.6.5. 1. 초기화하기
<python />
dp = [[1]*(m+1) for _ in range(m+1)] # dp 리스트를 m만큼 생성한다. 그리고 모든 수를 1로 만든다.
모든 수를 1로 만드는 이유는 dp의 행렬 같다면 1이기 때문에 먼저 삽입하였습니다.
1.0.6.6.
파이썬 이중 배열 선언 초기화 컴프리헨션
🤔 이중배열 컴프리헨션이란? 이중배열 컴프리헨션(Double List Comprehension)은 중첩된 리스트를 생성하는 방법 중 하나입니다. 🤯 이중배열 컴프리헨션의 기본 구조 [[expression] for element in iterable if
night-knight.tistory.com
1.0.6.7. 참조
1.0.6.8. 2. n이 1 이라면 경우의 수는 m
<code />
for i in range(2,m+1):
dp[1][i]=i
1.0.6.9.
1.0.6.10.
1.0.6.11. 3. 점화식을 활용한 dp배열 삽입
<code />
for i in range(2,n+1):
for j in range(i+1,m+1):
dp[i][j] = dp[i-1][j-1] + dp[i][j-1]
위 표의 규칙성을 이용한 점화식을 사용
1.1. 전체 코드
<python />
def dp_b (n,m) :
dp = [[1]*(m+1) for _ in range(m+1)]
for i in range(2,m+1):
dp[1][i]=i
for i in range(2,n+1):
for j in range(i+1,m+1):
dp[i][j] = dp[i-1][j-1] + dp[i][j-1]
return dp[n][m]
for _ in range(int(input())):
west, east = map(int, input().split())
print(dp_b(west,east))
GitHub - SeokJuGo/Studing_CodingTest: CodingTestPractice
CodingTestPractice. Contribute to SeokJuGo/Studing_CodingTest development by creating an account on GitHub.
github.com
'코딩테스트 > 백준' 카테고리의 다른 글
[백준][1003] - 피보나치 함수 python 파이썬 (2) | 2023.04.19 |
---|---|
[백준][11866] - 요세푸스 문제 python 파이썬 (0) | 2023.04.19 |
[백준][10845][Silver 4] - 큐 python (0) | 2023.04.16 |
[백준][1427][Silver 5] - 소트인사이드 python (0) | 2023.04.14 |
[백준][2839][Silver 4] - 설탕배달 python (0) | 2023.04.13 |