Computer Science
탄탄한 기반 실력을 위한
전공과 이론 지식 모음
Today I Learned!
배웠으면 기록을 해야지
TIL 사진
Flutter 사진
Flutter로 모바일까지
거꾸로캠퍼스 코딩랩 Flutter 앱개발 강사
스파르타코딩클럽 즉문즉답 튜터
카카오테크캠퍼스 3기 학습코치
프로필 사진
박성민
임베디드 세계에
발을 들인 박치기 공룡
임베디드 사진
EMBEDDED SYSTEM
임베디드 SW와 HW, 이론부터 실전까지
ALGORITHM
알고리즘 해결 전략 기록
🎓
중앙대학교 소프트웨어학부
텔레칩스 차량용 임베디드 스쿨 3기
애플 개발자 아카데미 1기
깃허브 사진
GitHub
프로젝트 모아보기
Instagram
인스타그램 사진

Develop/알고리즘

[백준] 1904 - 01타일

sm_amoled 2021. 12. 25. 13:15

문제링크

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

문제

지원이에게 2진 수열을 가르쳐 주기 위해, 지원이 아버지는 그에게 타일들을 선물해주셨다. 그리고 이 각각의 타일들은 0 또는 1이 쓰여 있는 낱장의 타일들이다.

어느 날 짓궂은 동주가 지원이의 공부를 방해하기 위해 0이 쓰여진 낱장의 타일들을 붙여서 한 쌍으로 이루어진 00 타일들을 만들었다. 결국 현재 1 하나만으로 이루어진 타일 또는 0타일을 두 개 붙인 한 쌍의 00타일들만이 남게 되었다.

그러므로 지원이는 타일로 더 이상 크기가 N인 모든 2진 수열을 만들 수 없게 되었다. 예를 들어, N=1일 때 1만 만들 수 있고, N=2일 때는 00, 11을 만들 수 있다. (01, 10은 만들 수 없게 되었다.) 또한 N=4일 때는 0011, 0000, 1001, 1100, 1111 등 총 5개의 2진 수열을 만들 수 있다.

우리의 목표는 N이 주어졌을 때 지원이가 만들 수 있는 모든 가짓수를 세는 것이다. 단 타일들은 무한히 많은 것으로 가정하자.

입력

첫 번째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 1,000,000)

출력

첫 번째 줄에 지원이가 만들 수 있는 길이가 N인 모든 2진 수열의 개수를 15746으로 나눈 나머지를 출력한다.

조건

  • 시간 제한 : 0.75s
  • 메모리 제한 : 256MB

해설

00 또는 1을 붙여서 N자리의 수열을 만들어내면 된다. 5자리 수열을 만들 때는 3자리 수열 맨 뒤에 00을 붙이거나 4자리 수열 맨 뒤에 1을 붙이면서 수열을 만들어나가면 모든 경우의 수열을 만들 수 있다.

풀이

이를 위해 dp 벡터를 선언해주고, 0으로 초기화해준다. 1, 2자리 수의 경우 1 / 00, 11 로 구성할 수 있기 때문에, 초깃값으로 1, 2를 담아주었다. dp 벡터의 크기를 N+1로 잡아준 이유는 index와 자릿수를 통일하여 가독성을 높이기 위해서이다.

int N;
cin >> N;
vector<int> dp(N+1, 0);

dp[1] = 1;
dp[2] = 2;

N자리 수열을 만들 때는 N-2자리 수열에 00을 붙이거나 N-1자리 수열에 1을 붙이면 된다. 맨 뒤에 붙이면서 수열을 만들면 중복 없이 만들 수 있다. 이를 코드로 구현하면 아래와 같다. 문제에서 15746으로 나눈 나머지를 구하고자 하였으므로 해당 값으로 나눈 경우의 수를 dp[i]에 넣어주었다.

for(int i = 3; i < N+1; i++) {
    dp[i] = (dp[i-1] + dp[i-2])%15746; 
    
}

dp[N]에 원하는 결과가 들어있어서, 이 값을 출력하면 된다.


코멘트

쉽다 쉬워! 군생활 94일 남았네 ㅎㅎ


코드

#include <iostream>
#include <vector>

using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    
    int N;
    cin >> N;
    vector<int> dp(N+1, 0);
    
    dp[1] = 1;
    dp[2] = 2;
    
    for(int i = 3; i < N+1; i++) {
        dp[i] = (dp[i-1] + dp[i-2])%15746; 
        
    }
    
    cout << dp[N];
    return 0;
}
320x100