개발 지식/알고리즘

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

트리맨스 2019. 6. 6. 15:36
반응형

문제 : 정수 n이 주어졌을 때, n 을 1,2,3 의 합으로 나타내는 방법의 수를 구하는 프로그램을 만들어라.


예시) 4를 1,2,3의 합으로 나타내는 방법은 7가지가 있다.

1+1+1+1

1+1+2

1+2+1

2+1+1

2+2

1+3

3+1


입력) 첫째줄에 테스트 개수 T 가 주어지고, 각 케이스는 1줄, 출력은 각 경우당 1줄 출력한다.


나는 이 문제를 동적 계획법으로 풀었다. 여러가지 해결법이 있었으나, 가장 합리적으로 보였다.

(동적 계획법이란, 문제를 해결하기 위해 이전의 데이터를 이용하는 경우 메모리 어딘가에 저장해 두었다가 다시 꺼내와서 계산하는 방식이다. 주로 배열을 이용한다. 이 방식을 이용하면 함수를 부르는 것에 비해 컴퓨터 자원을 적게 소모하게 된다.)


1일 경우를 생각해보면, 1밖에 없다. 즉 1가지가 있다.

2일 경우를 생각해보면, 1+1 과 2 밖에 없다. 즉 2가지 이다.

3일 경우를 생각해보면, 1+1+1, 1+2, 2+1, 3 이다. 즉 4가지 이다.

이런식으로 계속 수를 늘려보자. 


4일 경우에는 3인 경우에 +1을 뒤에 붙여서 4가지의 경우를 생각할 수가 있다. 또 2일 경우에 뒤에 +2를 붙여서 2가지 경우를 생각해낸다. 마지막으로 1인 경우 뒤에 +3을 붙여서 1가지의 경우를 생각할 수가 있다. 이러한 식으로 계속 지나가다 보면, n 의 방법의 가짓수는 [n-1의 가짓수 + n-2의 가짓수 + n-3의 가짓수] 라는 공식이 성립하게 된다. 이것을 이용해 간단한 코드를 짜 보았다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
 
int a[15];
 
int plus(int n)
{
    if(n==1return 1;
    if(n==2return 2;
    if(n==3return 4;
    if(a[n]!=0)
    {
        return a[n];
    }
    return a[n]=plus(n-1)+plus(n-2)+plus(n-3);
}
 
int main()
{
    int num,j;
    scanf("%d",&num);
    for(int i=0;i<num;i++)
    {
        scanf("%d",&j);
        printf("%d\n",plus(j));
    }
}
cs


내가 생각한 방법은 동적 계획법을 이용해 풀었으나, 일반적인 배열에 저장해 두는 식으로 만들어 풀어도 상관없을 것 같다. 하지만 함수를 이용해 깔끔하게 모듈화를 하면 보기에도 좋을 것 같다는 생각이 든다.

반응형

'개발 지식 > 알고리즘' 카테고리의 다른 글

[백준] 4673 셀프 넘버  (0) 2019.06.30
[백준] 11720 숫자의 합  (0) 2019.06.15
[백준] 1463 1로 만들기  (0) 2019.05.27
[백준] 14786 Ax+Bsin(x)=C (2)  (8) 2019.05.24
[백준] 1010 다리 놓기  (0) 2019.05.08