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

Develop/알고리즘

[백준] 9095 - 1, 2, 3 더하기

sm_amoled 2021. 8. 9. 13:12

문제링크

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

문제

정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 7가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다.

  • 1+1+1+1
  • 1+1+2
  • 1+2+1
  • 2+1+1
  • 2+2
  • 1+3
  • 3+1

정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다. n은 양수이며 11보다 작다.

출력

각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 출력한다.

조건

  • 시간 제한 : 1s
  • 메모리 제한 : 512MB

해설

숫자 N을 구성하기 위해 마지막으로 선택한 동전의 종류에 따라 1인 경우, 2인 경우, 3인 경우에 대해 N-1, N-2, N-3을 구성하는 경우의 수를 이용하면 1, 2, 3의 합으로 나타내는 방법의 수를 쉽게 구할 수 있다.

풀이

다이나믹 프로그래밍 방식을 적용하여 풀면 쉽게 해결이 가능한 문제이다.

다이나믹 프로그래밍을 적용하기 위한 조건은 1. 작은 문제가 반복적으로 일어나고, 2. 같은 문제의 답은 항상 같아야 하는데, 이 문제에서는 N에 대해서 N-1, N-2, N-3으로 문제를 나누어 작은 문제를 통해 큰 문제를 해결할 수 있어 적용하기에 적절하다.

4를 예로 들어보자.
1. 3을 마지막으로 선택한 경우 (1에 3 추가)
		1 +3
2. 2를 마지막으로 선택한 경우 (2에 2 추가)
		1+1 +2
		2 +2
3. 1을 마지막으로 선택한 경우 (3에 1 추가)
		1+1+1 +1
		1+2 +1
		2+1 +1
		3 +1
→ 1+1+1+1 1+1+2 1+2+1 2+1+1 2+2 3+1 1+3 모두 커버 가능

위 예시를 통해 N의 경우의 수는 N-1의 경우의 수 + N-2의 경우의 수 + N-3의 경우의 수와 같음을 알 수 있다. 이를 식으로 옮기면 아래와 같다.

arr[N] = arr[N-1] + arr[N-2] + arr[N-3];

k가 3보다 작거나 같은 경우에는 1, 2, 3 동전을 추가하는 특수한 경우이므로 예외처리 하였고, 나머지 k가 3보다 큰 경우에 대해서 일반항을 적용하여 값을 구한 뒤, 구하고자 하는 N의 값을 구한다.

int n;
cin >> n;
vector<int> arr(n+1);

for(int k = 1; k <= n; k++) {
    if(k > 3) {
        arr[k] = arr[k-1] + arr[k-2] + arr[k-3];
    } else{
        if(k==1) arr[k] = 1;
        else if (k==2) arr[k] = 2;
        else arr[k] = 4;
    }
}

printf("%d\n", arr[n]);


코멘트

매우 단순하고 쉬운 DP문제!


코드

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main () {
    int t;
    cin >> t;
    for(int i = 0; i < t; i++) {
        int n;
        cin >> n;
        vector<int> arr(n+1);
        
        for(int k = 1; k <= n; k++) {
            if(k > 3) {
                arr[k] = arr[k-1] + arr[k-2] + arr[k-3];
            } else{
                if(k==1) arr[k] = 1;
                else if (k==2) arr[k] = 2;
                else arr[k] = 4;
            }
        }
        printf("%d\n", arr[n]);
    }

    return 0;
}
320x100

'Develop > 알고리즘' 카테고리의 다른 글

[백준] 1932- 정수 삼각형  (0) 2021.08.09
[백준] 11726 - 2xn 타일링  (0) 2021.08.09
[백준] 8983 - 사냥꾼  (1) 2021.08.09
[백준] 2467 - 용액  (0) 2021.08.09
[백준] 2776 - 암기왕  (0) 2021.08.09