[C++] 백준 15989번: 1, 2, 3 더하기 4

2024. 10. 5. 19:01·problem solving/백준

🔗 문제

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

✏️ 풀이

 

이 문제가 어려운 이유는 중복 순서가 허용되지 않기 때문이다. 

 

당연히 숫자를 바텀업 방식으로 이전의 숫자를 만드는 방법을 활용해야겠다는 생각이 든다. 

이게 바로 dp 구나 깨닫는 과정 같은데 점화식 만드는 게 쉽지 않다. 

 

나는 이 문제를 완전 탐색으로도 못 짜겠어서 고생을 했다!

그래도 문제가 1, 2, 3으로만 이루어져 있다는걸 생각하면 활용할 수 있다. 

 

이 문제는 점화식을 만드는 과정이 아니라 설명을 하는게 맞는 것 같다. 

DP.resize(MAX, vector<int>(4, 0)); // 1, 2, 3 인덱스를 사용하기 위한 사이즈 조정

DP[0][1] = DP[1][1] = DP[2][1] = DP[2][2] = 1; // bottom-up을 위한 초기 설정

for(int i=3; i<MAX; ++i)
{
    DP[i][1] = DP[i - 1][1];
    DP[i][2] = DP[i - 2][1] + DP[i - 2][2];
    DP[i][3] = DP[i - 3][1] + DP[i - 3][2] + DP[i - 3][3];
}

 

DP[i][k] : i번째 숫자를 만드는 구성 요소가 마지막 숫자가 k인 "경우의 수"

 

 

우리가 구해야할 숫자가 4라고 했을 때, 각 DP에 들어갈 수 있는 방법은 아래와 같다. 

  • `DP[4][1]` : {1, 1, 1, 1}
  • `DP[4][2]` : {1, 1, 2}, {2, 2}
  • `DP[4][3]` : {1, 3}

그래서 정답은` DP[4][1] + DP[4][2] + DP[4][3]`이 된다. 

 

그럼 이 DP의 값은 어떻게 채우느냐? 

k에 1이 들어가기 위해서 DP[i-1]값이 필요하고,

k에 2가 들어가기 위해서는 DP[i-2]값이 필요하다. 

식을 보면 k보다 큰 값은 더하지 않기 때문에 오름차순을 지켜 중복 순서가 허용되지 않는다.

 

💾  소스

#include <iostream>
#include <vector>
using namespace std;

const int MAX = 10001;
vector<vector<int>> DP;

void solve()
{
    DP.resize(MAX, vector<int>(4, 0));
    DP[0][1] = DP[1][1] = DP[2][1] = DP[2][2] = 1;

    for(int i=3; i<MAX; ++i)
    {
  		DP[i][1] = DP[i - 1][1];
  		DP[i][2] = DP[i - 2][1] + DP[i - 2][2];
  		DP[i][3] = DP[i - 3][1] + DP[i - 3][2] + DP[i - 3][3];
    }

}

int main() 
{
    int T, n;
    cin >> T;
    
    solve();
    
    while(T--)
    {
        cin >> n;
        cout << DP[n][1] + DP[n][2] + DP[n][3]  << "\\n";
    }
    
    return 0;
}
저작자표시 비영리 변경금지 (새창열림)
'problem solving/백준' 카테고리의 다른 글
  • [C++] 백준 1063번 : 킹
  • [C++] 백준 17299번: 오등큰수
  • [C++] 백준 1445번 : 일요일 아침의 데이트
  • [C++] 백준 13549번: 숨바꼭질3
u1qns
u1qns
http://github.com/u1qns
  • u1qns
    개발 블로그
    u1qns
  • 전체
    오늘
    어제
    • 분류 전체보기 (173)
      • 회고 (1)
      • programming (17)
        • 개념 정리 (6)
        • CI CD (1)
        • 트러블 슈팅 (0)
        • 환경설정 및 팁 (7)
      • problem solving (155)
        • 개념 정리 (3)
        • 백준 (129)
        • SWEA (15)
        • 프로그래머스 (4)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

    • 깃허브
  • 공지사항

  • 인기 글

  • 태그

    SSAFY수료식
    boj
    구현
    삼성청년SW아카데미
    POW
    HELLOSSAFY
    DFS
    cpp
    백준
    완전탐색
    cmath
    되추적
    BFS
    DP
    투포인터
    SSAFY
    그리디
    미해결
    SWEA
    C++
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
u1qns
[C++] 백준 15989번: 1, 2, 3 더하기 4
상단으로

티스토리툴바