[백준]11049번 행렬 곱셈 순서(python 파이썬)
by 코딩무비저번 풀이에 이어 dp의 대표적인 문제를 하나 풀어보겠습니다!
참고로 pypy3으로 제출해야 합니다!
문제
11049번: 행렬 곱셈 순서
첫째 줄에 입력으로 주어진 행렬을 곱하는데 필요한 곱셈 연산의 최솟값을 출력한다. 정답은 231-1 보다 작거나 같은 자연수이다. 또한, 최악의 순서로 연산해도 연산 횟수가 231-1보다 작거나 같
www.acmicpc.net
아이디어
행렬이 A, B, C, D가 있다고 가정해봅시다
행렬 곱셈 연산 경우의 수는 다음과 같습니다
A(BCD) -> A((BC)D)
-> A(B(CD))
(AB)(CD)
(ABC) D -> (A(BC))D
-> ((AB) C))D
규칙 발견
행렬 i번째에서 j까지의 연산을 계산하기 위해서는
dp[i][j]는 행렬 i에서 j까지의 곱셈 연산 수를 의미합니다.
dp[i][j]의 값은 이 수식들 중 가장 작은 값입니다.
dp[i][i+0] + dp[i+1][j] + A[i][0]*A[i+1][0]*A[j][1]
dp[i][i+1] + dp[i+2][j] + A[i][0]*A[i+2][0]*A[j][1]
.......
dp[i][j-2] + dp[j-1][j] + A[i][0]*A[j-2][0]*A[j][1]
dp[i][j-1] + dp[j][j] + A[i][0]*A[j-1][0]*A[j][1]
이를 코드로 나타내면 다음과 같습니다.
for i in range(n-1,-1,-1):
for j in range(i+1,n):
dist = j-i
for k in range(dist):
dp[i][j] = min(dp[i][j],dp[i][i+k]+dp[i+k+1][j]+A[i][0]*A[i+k][1]*A[j][1])
전체 코드
import sys
input = sys.stdin.readline
INF = sys.maxsize
n = int(input())
A = []
for _ in range(n):
r,c = map(int,input().split())
A.append((r,c))
dp = [[INF for _ in range(n)] for _ in range(n)]
for i in range(n):
dp[i][i] = 0
# dp[i][j] = i에서 j까지 연산할 때의 최소 연산
for i in range(n-1,-1,-1):
for j in range(i+1,n):
dist = j-i
for k in range(dist):
dp[i][j] = min(dp[i][j],dp[i][i+k]+dp[i+k+1][j]+A[i][0]*A[i+k][1]*A[j][1])
print(dp[0][-1])
잘못된 내용이 있으면 피드백 부탁드립니다!
궁금한 내용이 있으면 언제든지 물어보세요!!!
'문제풀이(ps)' 카테고리의 다른 글
[프로그래머스] SQL 코테 정복하기 (14) | 2022.04.29 |
---|---|
[백준] 17070번 파이프 옮기기 1 (python 파이썬) (10) | 2022.04.28 |
[백준] 12865번 평범한 배낭(python 파이썬) (6) | 2022.04.25 |
[백준] 12015번 가장 긴 증가하는 부분 수열 2(python 파이썬) (5) | 2022.04.23 |
[프로그래머스] 가장 먼 노드(python 파이썬) (8) | 2022.04.21 |
블로그의 정보
코딩무비
코딩무비