【Algorithm】[프머] DP - N으로 표현

1. 첫번째 코드 - DFS

알고리즘 프로그래머스 P2

  • first.py의 문제점 (44점)
    1. DFS 는 복잡하다. BFS 사용하자 -> 해결 NO
    2. 33 + 33 는 해결하지 못한다 -> 해결 YES ```python

      DFS 는 복잡하다. BFS 사용하자

      def solution(N, number): array = [10] * 32001 mark = [0] * 32001 temp = [1,11,111,1111,11111]

    def dynamic(checkN, count, i): if not(0<checkN <32001) : return if count > 8 : return # if mark[checkN] == i: # return if count > array[number]: return

      array[checkN] = count
      mark[checkN] = i
    
      if checkN == number:
          print(array[number], mark[checkN])
          return
      else:
          dynamic(checkN+N, count+1, i)
          dynamic(checkN-N, count+1, i)
          dynamic(checkN*N, count+1, i)
          dynamic(checkN//N, count+1, i)
    

    l = 5 if N < 3 else 4 for i in range(1,l): start = temp[i-1] * N dynamic(start, i, i)

    answer = array[number] if array[number] < 9 else -1 return answer

if name == “main”: print(solution(5,12))


# 2. 두번쨰 코드 - DFS
![image](https://user-images.githubusercontent.com/46951365/95305692-4be5e500-08c1-11eb-9629-ab6c6cc50af4.png)
- second.py의 문제점 (77점)
    1. 8을 return 해도 된는가               -> 7까지만 return 하도록 하면, 점수 떨어짐. 즉 8 return해야 함.
    2. 5, 26 = 5*5 + 5/5 로써 4가 답으로 나와야 함. But 나의 코드는 5가 나옴. ) "((5*5)+5)/5)"식으로 연산이 이뤄지기 떄문이다.
```python
def solution(N, number):
    array = [10] * 32001
    esses = [N*i for i in [1,11,111,1111,11111] if N*i < 32001]  # good
    print(esses)
    
    def dynamic(checkN, count):
        if not(0<checkN <32001) :
            return
        if count > 8 :  # 8도 return 가능
            return
        if count > array[number]:
            return
    
        array[checkN] = count

        if checkN == number:
            return
        else:
            for j, nu in enumerate(esses):
                dynamic(checkN+nu, count+j+1)
                dynamic(checkN-nu, count+j+1)
                dynamic(checkN*nu, count+j+1)
                dynamic(checkN//nu, count+j+1)

    for i, num in enumerate(esses):     # good
        dynamic(num, i+1)
    
    answer = array[number] if array[number]  < 9 else -1    # 8도 return 가능
    return answer


if __name__ == "__main__":
    print(solution(5,26))

3. 세번쨰 코드 - Danamic programming

  • 정답 참조 링크는 게시물 맨 위에 있음.
  • Danamic programming 문제를 풀기 위해서는 재귀식을 세우는게 가장 중요하다.
  • 핵심 재귀식은 다음과 같다.
      N을 n번 사용해서 만들 수 있는 수 :
          N을 n번 연달아서 사용할 수 있는 수 U(합집합)
          N을 1번 사용했을 때 SET 과 n-1번 사용했을 때 SET을 사칙연산한 수들의 집합 U
          N을 2번 사용했을 때 SET 과 n-2번 사용했을 때 SET을 사칙연산한 수들의 집합 U
          ... U
          N을 n-1번 사용했을 때 SET 과 1번 사용했을 때 SET을 사칙연산한 수들의 집합
    
  • 나의 손코딩

  • 나의 코드
def solution(N, number):
    S = [0]
    for i in range(1,9):
        S.append({int(str(N)*i)})
    for i in range(1,9):
        for j in range(1,i):
            print(i,j,i-j)
            # set은 순서가 없기 때문에 list로 바꿔서 for해야하는 줄 알았는데 
            # 이런 방법으로 set내부의 모든 원소에 쉽게 접근할 수 있다. dict도 마찬가지 이다. 
            for num1 in S[j]: 
                for num2 in S[i-j]:
                    S[i].add(num1+num2)
                    S[i].add(num1-num2)
                    S[i].add(num1*num2)
                    if num2 != 0:
                        S[i].add(num1//num2)
        if number in S[i]:
            return i
    return -1



if __name__ == "__main__":
    print(solution(5,))

"""
위의 print로 나오는 수
2 1 1
3 1 2
3 2 1
4 1 3
4 2 2
4 3 1
5 1 4
5 2 3
5 3 2
5 4 1
6 1 5
6 2 4
6 3 3
6 4 2
6 5 1
7 1 6
7 2 5
7 3 4
7 4 3
7 5 2
7 6 1
8 1 7
8 2 6
8 3 5
8 4 4
8 5 3
8 6 2
8 7 1
"""

4. 참고하면 좋은 정답 코드

  • 참조 사이트는 맨 위에 기제.
  • 참조 사이트의 손 코딩도 읽으면 매우 좋으니 참조 할 것.
      def solution(N, number):
          # 허뎝님의 수정 피드백 -> 테스트 케이스가 바뀌면서 예외 사항을 추가해야 함.
          if N == number:
              return 1
                
          # 1. [ SET x 8 ] 초기화
          s = [ set() for x in range(8) ] 
          # 2. 각 set마다 기본 수 "N" * i 수 초기화
          for i,x in enumerate(s, start=1):
              x.add( int( str(N) * i ) )
          # 3. n 일반화
          #   { 
          #       "n" * i U 
          #       1번 set 사칙연산 n-1번 set U
          #       2번 set 사칙연산 n-2번 set U
          #       ...
          #       n-1번 set 사칙연산 1번 set, 
          #    } 
          # number를 가장 최소로 만드는 수 구함.
          for i in range(1, 8):
              for j in range(i):
                  for op1 in s[j]:
                      for op2 in s[i-j-1]:
                          s[i].add(op1 + op2)
                          s[i].add(op1 - op2)
                          s[i].add(op1 * op2)
                          if op2 != 0:
                              s[i].add(op1 // op2)
              if  number in s[i]:
                  answer = i + 1
                  break
          else:
              answer = -1
          return answer
    

© All rights reserved By Junha Song.