[백준][Python3] 20500 - Ezreal 여눈부터 가네 ㅈㅈ

2021. 1. 24. 17:30·알고리즘 (PS)/BOJ
반응형

https://www.acmicpc.net/problem/20500

 

20500번: Ezreal 여눈부터 가네 ㅈㅈ

문제의 답을 $1\,000\,000\,007$로 나눈 나머지를 출력한다.

www.acmicpc.net

초급 알고리즘 DP 강의를 수강 후 연습문제로 풀게된 문제이다.

 

문제는 간단하다

1과 5로 이루어진 N자리 수 중 15의 배수를 구하는 문제이다.

어떻게하면 이 문제를 DP를 활용하여 구할 수 있을까?

 

아무런 아이디어가 떠오르지 않았다.

그래서 그냥 무작정 써봤다.

 

1자리수

1, 5

0개

 

2자리수

11, 15, 51, 55

1개

 

3자리수

111, 115, 151, 155, 511, 515, 551, 555

 

근데 3자리수를 쓰고보니 15의 배수가 한눈에 안보인다.

일일히 나눠보는 생각을 했지만 귀찮았다.

 

그러던 중 한가지 아이디어가 떠올랐다.

https://www.acmicpc.net/problem/2248

 

2248번: 이진수 찾기

N(1 ≤ N ≤ 31)자리의 이진수가 있다. 이러한 이진수 중에서, L(1 ≤ L ≤ N)개 이하의 비트만 1인 것을 크기 순으로 나열했을 때, I번째로 나오는 이진수를 구해내는 프로그램을 작성하시오. 이진수

www.acmicpc.net

2248번 이진수 찾기 문제를 푸는 과정을 떠올려보았다.

N자리 이진수 중 1을 M개 이하로 사용하여 크기순으로 나열한 이진수 중

K번째 수를 구하는 문제이다.

이 문제를 풀 때, 각각의 자리수에서 얻은 값을 활용하여 다음 자리수의 값을 구하였다.

 

이 문제도 혹시 그렇게 풀 수 있지 않을까?

앞 자리수로 1 또는 5가 추가될 수 있다.

1 또는 5가 추가된다는 것은 다음과 같은 의미를 지닌다.

 

1자리수에서 2자리수로 갈 때

앞자리수로 1이 추가된다 = 10을 더한다

앞자리수로 5가 추가된다 = 50을 더한다

 

그런데 어떤 두 수를 더한 값의 나머지는

그 두 수 각각의 나머지의 합의 나머지와 같다.

10 + 16 을 3으로 나눈 나머지는 얼마일까?

3 * 8 = 24 이므로

26의 나머지는 2이다.

 

하지만 다음과 같이 구할 수도 있다.

10 = 3*3 + 1 이므로 나머지가 1이다.

16 = 3*5 + 1 이므로 나머지가 1이다.

따라서 두 수를 더한 값의 나머지는 1+1 = 2 이다.

 

이것을 이 문제에 적용해보자.

어떤 수에 10을 더했을 때 그 결과가 15의 배수

즉, 15로 나눈 나머지가 0 이려면

그 어떤 수의 나머지는 얼마여야할까?

그렇다 바로 나머지가 5이면 된다.

 

어떤 수에 50을 더했을 때 그 결과가 15의 배수

즉, 15로 나눈 나머지가 0이려면

그 어떤 수의 나머지는 얼마여야할까?

50을 15로 나눈 나머지는 15*3 + 5 에서 5이다.

따라서 어떤 수의 나머지는 10이면 된다.

 

다음과 같이

1_  /  5_ 인 수가 있다고 한다면

저 1의자리의 나머지가 왼쪽의 경우 5

오른쪽의 경우 10이면 된다.

 

따라서 2자리수 일 때 15의 배수는 15 하나이다.

 

한번 다음자리수로 확장해서 생각해보자.

1 _ _ / 5 _ _ 인 수에 대해서 생각할 때

1 _ _  = 100 + _ _ 

5 _ _ = 500 + _ _

여기에서 우리는 놀라운 점을 알 수 있다.

100을 15로 나누어보면 15*6 + 10 이므로 나머지가 10이다!

500을 15로 나누어보면 15*33 + 5 이므로 나머지가 5이다!

 

즉 10, 100, 1000, 10000, .... 의 15로 나눈 나머지는 모두 10이고

50, 500, 5000, 50000, ... 의 15로 나눈 나머지는 모두 5이다.

 

따라서 위의 경우 1 _ _ 일 때는 _ _ 의 나머지가 5인 수를 더해주고

5 _ _ 일 때는 _ _ 의 나머지가 10인 수를 더해주면 된다.

 

여기까지 생각을 했다면 이를 어떻게 dp로 바꿔줄 수 있을까?

한가지만 더 생각하면 된다.

기존 15의 배수 앞자리 수에 1과 5를 채우면 나머지가 어떻게 될까?

1을 채울 땐 나머지가 0에서 10이되고

5를 채울 땐 나머지가 0에서 5가 된다.

 

여기에서 나머지가 0, 5, 10 으로만 구성된다는 것을 알 수 있다.

(마지막자리가 1로 끝나는 경우는 나머지는 1, 6, 11 중 하나가 될 것이지만,

그 경우에는 절대로 15의 배수를 만들 수 없으므로 생각하지 않는다.)

 

그렇다면 이걸 서로 돌려가며 활용하면 된다.

 

현재 자리수에서 나머지가 0인 수의 개수는

이전 자리수에서 나머지가 5인 수의 개수 + 나머지가 10인 수의 개수 이다.

나머지가 5인수 앞에 1을 붙이면 되고

나머지가 10인수 앞에 5를 붙이면 되기 떄문이다.

 

현재 자리수에서 나머지가 5인 수의 개수는

이전 자리수에서 나머지가 0인 수의 개수 + 나머지가 10인 수의 개수 이다.

 

현재 자리수에서 나머지가 10인 수의 개수는

이전 자리수에서 나머지가 0인 수의 개수 + 나머지가 5인 수의 개수이다.

이 두가지 경우의 이유 역시 위의 이유와 비슷하다.

자리수 나머지가 0인 수의 개수 나머지가 5인 수의 개수 나머지가 10인 수의 개수
1 0 1 0
2 1 0 1
3 1 2 1
4 3 2 3

점화식이 매우 간단하다!

이제 매번 나머지의 개수를 구할 때 문제에서 말한대로 1000000007로 나눠주는 과정을 섞어주고

마지막엔 구하는 자리수의 나머지가 0인 수의 개수를 출력하면 된다.

 

구현한 코드는 다음과 같다.

# 20500 Ezreal 여눈부터 가네 ㅈㅈ
dp = [[0 for _ in range(3)] for _ in range(1516)]
dp[1][1] = 1
for i in range(2, 1516):
    dp[i][0] = dp[i-1][1] + dp[i-1][2]
    dp[i][1] = dp[i-1][0] + dp[i-1][2]
    dp[i][2] = dp[i-1][0] + dp[i-1][1]
    for j in range(3):
        dp[i][j] %= 1000000007
print(dp[int(input())][0])

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'알고리즘 (PS) > BOJ' 카테고리의 다른 글

[백준][C++] 9935 문자열폭발  (0) 2021.02.13
[백준][C++] 19541 루머  (0) 2021.02.08
[백준][Python3] 2878 - 캔디캔디  (0) 2021.01.19
[BOJ][Python3] 5520 - The Clocks  (0) 2021.01.18
[BOJ][Python3/PyPy3] 7579 - 앱  (0) 2021.01.16
'알고리즘 (PS)/BOJ' 카테고리의 다른 글
  • [백준][C++] 9935 문자열폭발
  • [백준][C++] 19541 루머
  • [백준][Python3] 2878 - 캔디캔디
  • [BOJ][Python3] 5520 - The Clocks
에버듀
에버듀
개발은 좋은데 뭘로 개발할까
  • 에버듀
    Blog. 에버듀
    에버듀
  • 전체
    오늘
    어제
    • 분류 전체보기 (615)
      • 개인 프로젝트 (43)
        • 토이 프로젝트 (3)
        • [2020] 카카오톡 봇 (9)
        • [2021] 코드악보 공유APP (22)
        • [2022] 유튜브 뮤직 클론코딩 (9)
        • [2025] 한글 SQL 데이터베이스 (0)
      • 팀 프로젝트 (22)
        • [2020] 인공지능 숫자야구 (4)
        • [2022] OSAM 온라인 해커톤 (10)
        • [2024] GDSC 프로젝트 트랙 (6)
        • [2025] 큰소리 웹 페이지 (2)
      • CS (335)
        • 자료구조 (19)
        • 어셈블리 (41)
        • 멀티미디어응용수학 (7)
        • 컴퓨터 구조 (29)
        • 알고리즘 분석 (4)
        • 컴퓨터 네트워크 (38)
        • 프로그래밍언어론 (15)
        • HCI 윈도우즈프로그래밍 (26)
        • 기초데이터베이스 (29)
        • 운영체제 (23)
        • 오토마타 (24)
        • 문제해결기법 (11)
        • 블록체인 (22)
        • 소프트웨어공학 (21)
        • 기계학습심화 (12)
        • 컴퓨터그래픽스와 메타버스 (8)
        • 분산시스템특론 (6)
      • 자기계발 (45)
        • 생각 정리 (23)
        • 대외활동 (11)
        • 동아리 (7)
        • 자격증 (3)
        • 머니 스터디 (1)
      • 알고리즘 (PS) (107)
        • BOJ (101)
        • Programmers (5)
        • 알고리즘 이모저모 (1)
      • WEB(BE) (8)
        • express.js (1)
        • Spring & Spring Boot (7)
      • WEB(FE) (2)
        • html, css, js (1)
        • React.js (1)
      • Tool & Language (6)
        • Edit Plus (1)
        • Git (1)
        • Python3 (2)
        • Java (2)
      • Infra (12)
        • AWS (1)
        • Oracle Cloud (8)
        • Firebase (2)
        • Network (1)
      • Android (18)
        • Java (6)
        • Flutter (12)
      • Window (2)
        • Visual Studio 없이 WPF (1)
        • MFC (1)
      • 독서 (14)
        • Inside Javascript (7)
        • Database Internals (6)
        • 한 글 후기 (1)
  • 링크

    • github
    • website
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
에버듀
[백준][Python3] 20500 - Ezreal 여눈부터 가네 ㅈㅈ
상단으로

티스토리툴바