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

2023/09/01~03까지 #201

Merged
merged 1 commit into from
Nov 19, 2023
Merged

2023/09/01~03까지 #201

merged 1 commit into from
Nov 19, 2023

Conversation

13wjdgk
Copy link
Contributor

@13wjdgk 13wjdgk commented Sep 6, 2023

문제

#197 호텔

해결 과정

import sys
readline = sys.stdin.readline
C,N = map(int,readline().rstrip().split())
city = [[] for i in range(N)]

maxPeople = -1
for n in range(N):
    cost,people = map(int,readline().rstrip().split())
    city[n]=[cost,people]
    maxPeople = max(maxPeople,people)

dp = [1e9 for i in range(C+maxPeople+1)]

for ind in range(1,len(dp)) :
    for cityInd in range(len(city)) :
        value = city[cityInd][1]
        needCost = city[cityInd][0]
        # 같을 때
        if value == ind :
            dp[ind] = min(dp[ind],needCost)
        # 배수로 나뉘어질 때
        elif (ind%value) == 0 :
            quotient = ind//value
            dp[ind] = min(dp[ind],needCost * quotient)
        # ind가 커서  이전 최소값에서 자신을 추가   
        elif value < ind :
            dp[ind] = min(dp[ind],dp[ind-value]+needCost)

result = 1e9
for r in range(C,C+maxPeople+1):
    result = min(result,dp[r])


print(result)
                    

다른분들의 풀이를 보니 내가 너무 복잡하게 푼 것 같다.

메모리, 시간

백준 문제일 경우 아래에 입력해주세요

  • 31256 KB
  • 52ms

#문제
숨바꼭질 3

나의 풀이 과정

  1. DP로 접근

    최소한의 시간을 구하는 문제여서, DP로 풀었었다.

    0부터 K*2까지 순서대로 지나가며 최소 시간을 구하는 로직을 짰었는데, 이때 수빈이의 현재 위치를 X라고 두고 X가 N보다 작을 때와 클때를 나눠 최소 시간을 구했다. (N에서 수빈이가 뒤로가는 경우도 있기 때문)

    1) X < N일 때

    N-1부터 0까지 수빈이가 위치할 때 N에서 걸리는 시간을 구했다.

    2) X > N일 때

    N+1부터 K*2까지 수빈이가 지나가면서 최소 시간을 구한다.

    수빈이의 현재 위치가 X일때 아래 두가지 시간 중 최소 시간을 저장한다.

    1️⃣ [X-1 위치의 최소 시간] + 1 ⇒ 이전 칸에서 한칸 걸은 경우

    2️⃣ [X/2 위치의 최소 시간] ⇒ x/2 위치에서 순간이동을 할 경우

    ↘️ 2번의 경우 , [ x-1 위치의 최소 시간]을 X위치로 순간이동한 후 , 뒤로 한칸 간 경우도 고려해줘야 한다.

    코드에서는 수빈이의 현재 위치를 ind라고 표현했다.

    # DP 풀이
    import sys
    readline = sys.stdin.readline
    N,K = map(int,readline().rstrip().split())
    start = min(N,K)
    finish = max(N,K)
    dp = [0 for _ in range(finish*2)]
    for ind in range(start-1,-1,-1):
        if ind*2 <=start:
            dp[ind] = min(dp[ind+1]+1 , dp[ind*2])
        else : dp[ind] = dp[ind+1]+1
    
    for ind in range(start+1,len(dp)) :
        if (ind % 2 == 0) and ((dp[ind-1]+1) >= dp[ind//2]) :
            dp[ind] = dp[ind//2]
            dp[ind-1] = min(dp[ind-1],dp[ind] + 1)
        else :
            dp[ind] = dp[ind-1]+1
    
    print(dp[finish])

    실패

    결국 저 코드는 틀렸다. 코드를 보면 틈틈이 틀린 부분이 있는데, 애초에 X < N일 때 [X *2위치의 최소시간]을 고려할 필요가 없다. N에서 뒤로 가는 과정이기 때문에 2배 앞으로 가는 방법은 있어도, 2배로 뒤로가는 과정은 없기 때문이다. 이뿐만 아니라 DP로 하게 되면 고려해야하는 경우가 너무 많다. 그래서 DP말고 다익스트라 알고리즘으로 풀었다.

  2. 다익스트라 알고리즘

다익스트라 알고리즘은 한 루트노드에서 비용이 적은 노드 순서대로 탐색하는 알고리즘이다. 다익스트라 최단 경로 알고리즘은 기본적으로 그리디 알고리즘으로 분류되는데 , ‘가장 비용이 적은 노드’를 선택해서 임의의 과정을 반복하기 때문이다.

예시로 N = 4, K = 6일 때 아래와 같이 그래프가 그려진다.

Untitled

한 노드당 고려해야하는 경우가 3가지 있다.

1️⃣ 2*X로 순간이동할 때

2️⃣ X-1 한칸 이동할 때

3️⃣ X+1 한칸 이동할 때

루트 노드에서 위의 3가지 경우를 고려하면 3,5,8노드가 나오고 각각의 간선에 비용이 생긴다. 그 중 가장 비용이 적은 순간이동을 먼저 탐색해야한다. 그럼 4 → 3 → 6 순서로 6을 탐색할 수 있게 된다.

import sys
from collections import deque
readline = sys.stdin.readline
N,K = map(int,readline().rstrip().split())
visited = [ -1 for _ in range(200001)]

queue = deque()
queue.append(N)
visited[N] = 0
while queue:
    node = queue.popleft()
    # 순간이동
    if node*2 < len(visited) and visited[node*2] == -1 :
        visited[node*2] = visited[node]
        queue.append(node*2)
        if node*2 == K :
            break
    # 뒤로 걷기
    if node-1 >=0 and visited[node-1] == -1  :
        visited[node-1] = visited[node]+1
        queue.append(node-1)
        if node-1 == K :
            break
    # 앞으로 걷기
    if node+1 < len(visited) and visited[node+1] == -1  :
        visited[node+1] = visited[node]+1
        queue.append(node+1)
        if node+1 == K :
            break

print(visited[K])

성공 🎉

@13wjdgk 13wjdgk self-assigned this Sep 6, 2023
@13wjdgk 13wjdgk added the 가은 label Sep 6, 2023
Copy link
Member

@GIVEN53 GIVEN53 left a comment

Choose a reason for hiding this comment

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

3문제 풀었군요 ! 짝짝

@13wjdgk 13wjdgk merged commit 0f11ea8 into main Nov 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants