Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

6-fnzksxl #28

Merged
merged 1 commit into from
Feb 18, 2024
Merged

6-fnzksxl #28

merged 1 commit into from
Feb 18, 2024

Conversation

fnzksxl
Copy link
Member

@fnzksxl fnzksxl commented Feb 15, 2024

🔗 문제 링크

등굣길

✔️ 소요된 시간

20분

✨ 수도 코드

저번에 성훈님께서 DP 문제 푸시는거 보고 저도 DP문제 한 번 풀어봤습니다!

이 문제는 DP의 메모이제이션 개념을 사용해서 문제를 풀어본 적이 있다면 금방 플 수 있을거라고 생각하는데요.
문제는 집에서 학교까지 갈 수 있는 최소 경로의 개수를 구하라고 하는데요.
사실상 고등학교 때 확통에서 풀었던 경로 경우의 수 구하는 문제랑 똑같은 것 같습니다.
차이점이라고 하면 오른쪽아래쪽으로만 움직여서 학교까지 가되 물웅덩이 부분은 경로에 포함하지 않겠다고 하는 점이죠.

확통 시간에 다들 이런 문제 하나 풀어보셨을겁니다.
시작 지점에서 끝지점 까지의 경우의 수 구하기!

image

저희는 이거 간단하게 어떻게 풀었죠?

image
(실제 코드에서도 solution(4.5,[]) 또는 solution(5,4,[])로 실행시켜 출력해보면 35가 나옵니다)

아래 그림처럼 물웅덩이가 생겼다면 그냥 피해서 가는 경우의 수를 계산하면 됩니다.
image

이를 코드로 옮겨볼까요.

  1. 메모이제이션을 위한 리스트 생성
  2. DP 초기값 생성
  3. DP 리스트에 물웅덩이 부분은 -1로 새로 지정 (이 후 연산에서 제외하기 위한 특수값)
  4. 테이블 순회하며 물웅덩이가 아닌 지역의 값들만 더하기

간단하죠?

전체코드

def solution(m, n, puddles):
    dp = [[0 for i_ in range(m+1)] for j in range(n+1)]
    
    dp[0][1] = 1
    
    for puddle in puddles:
        a,b = puddle
        dp[b][a] = -1
    
    for j in range(1,m+1):
        for i in range(1,n+1):
            if dp[i][j] == -1:
                continue
            elif dp[i-1][j] == -1:
                dp[i][j] = dp[i][j-1]
            elif dp[i][j-1] == -1:
                dp[i][j] = dp[i-1][j]
            else:
                dp[i][j] = (dp[i-1][j] + dp[i][j-1])
                
    return dp[n][m]%1000000007

📚 새롭게 알게된 내용

Copy link
Collaborator

@SeongHoonC SeongHoonC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코틀린 없어서 저도 파이썬으로 풀었습니다!
비슷한데 저는 이전이 -1 인지 체크 안하고 0이랑 비교해서 max 값을 넣어줘요!

def solution(m, n, puddles):
    answer = 0
    d = [[0]*(m+1) for _ in range(n+1)]
    d[1][1] = 1
    for puddle in puddles:
        d[puddle[1]][puddle[0]]=-1
    
    for i in range(1,n+1):
        for j in range(1,m+1):
            if (i==1 and j==1):
                continue
            if(d[i][j] == -1): 
                continue
            d[i][j] = max(d[i-1][j],0) + max(d[i][j-1],0)
                    
    return d[n][m]%1000000007

for i in range(1,n+1):
if dp[i][j] == -1:
continue
elif dp[i-1][j] == -1:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-1 이면 continue 이기 때문에 이미 else 를 내포한다고 생각합니다.
elif 가 아니라 if 인게 자연스러울 것 같아요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 그러게요..? 이게 훨씬 보기 좋네요

@@ -0,0 +1,21 @@
def solution(m, n, puddles):
dp = [[0 for i_ in range(m+1)] for j in range(n+1)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
dp = [[0 for i_ in range(m+1)] for j in range(n+1)]
dp = [[0]*(m+1) for _ in range(n+1)]

어느쪽이든 상관없지만 저는 이렇게 작성합니다!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리스트 컴프레헨션으로 쓸지 안 쓸지는 뭐랄까 그 날의 기분에 따라 달린 느낌이랄까요


for puddle in puddles:
a,b = puddle
dp[b][a] = -1
Copy link
Collaborator

@wkdghdwns199 wkdghdwns199 Feb 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

태원 님 혹시 여기서 웅덩이의 좌표를 b,a 이런식으로 반대로 설정하신 이유가 있나요? 뭔가 어떻게 해도 상관은 없을 거 같기는 한데.. 아닌가요? 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

b,a로 안하게 되면 만약에 2,1이 들어가게 되면 x -> 2 y ->1에 들어가야 하는데

홍준님이 말한대로 하면 dp[2][1]에 들어가게 되는데 그 부분에서
0 0 0 0 0
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
위와 같이 들어가게 되서 그런 것 같습니다!

dp[세로][가로]라서 그런 것 같습니다!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호 친절한 설명 감사합니다!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

민석님 말씀대로 이중리스트 만들면 [세로][가로] 라서 그렇습니다
미로 문제 풀다보면 아아- 그래서 그랬던거였군 하실 듯 합니다 ㅋㅋㅋㅋ

Copy link
Collaborator

@wkdghdwns199 wkdghdwns199 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이러한 풀이법은 진짜 머리속에서 바로 생각이 나는 건가요 🔥

@alstjr7437
Copy link
Member

alstjr7437 commented Feb 16, 2024

image

저도 위와 같이 노트에 정리를 하고 점화식 세워서 풀었는데 거의 비슷하네요!!
저는 따로 +1을 안하고 바로 해당부분부터 시작하도록 했습니다!!!
그리고 효율성에서 계속 막히길래 어디서 틀린지 모르겠어서 문제를 자세히 읽어보니 나눠야하더라구요...

def solution(m, n, puddles):
    answer = 0
    road = [[0] * m for i in range(n)]
    road[0][0] = 1
    for i in puddles:
        a,b = i
        road[b-1][a-1] = -1
    
    print(road)
    for i in range(n):
        for j in range(m):
            if i == 0 and j == 0 : 
                continue
            if road[i][j] == -1:
                continue
            elif road[i][j-1] == -1:
                road[i][j] = road[i-1][j]
            elif road[i-1][j] == -1:
                road[i][j] = road[i][j-1]
            else :
                road[i][j] = road[i][j-1] + road[i-1][j] 
    
    return road[n-1][m-1] %1000000007

@fnzksxl
Copy link
Member Author

fnzksxl commented Feb 18, 2024

@alstjr7437 ㅋㅋㅋㅋㅋㅋㅋㅋ 저도 나눠주는거 처음에 깜빡했다가 틀렸었어요

@fnzksxl fnzksxl merged commit 838c5c6 into main Feb 18, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants