Henu
개발냥발
Henu
전체 방문자
오늘
어제
  • 분류 전체보기 (411)
    • DevOps (52)
      • Kubernetes (19)
      • Docker (14)
      • AWS (3)
      • Nginx (4)
      • Linux (4)
      • ArgoCD (1)
      • CN (2)
      • NATS (0)
      • Git (5)
    • Back-End (30)
      • Django (18)
      • Spring (5)
      • JPA (1)
      • MSA (5)
    • CS (87)
      • SystemSoftware (20)
      • OS (25)
      • Computer Architecture (16)
      • Network (23)
      • Database (2)
    • Lang (21)
      • Java (9)
      • Python (4)
      • C# (8)
    • Life (12)
    • 블록체인 (2)
    • Algorithm (204)
      • BOJ (160)
      • 프로그래머스 (19)
      • LeetCode (4)
      • SWEA (1)
      • 알고리즘 문제 해결 전략 (8)
      • DS, algorithms (7)
      • Checkio (5)
    • IT (2)

블로그 메뉴

  • GitHub
  • 글쓰기
  • 관리자

공지사항

  • Free!

인기 글

태그

  • 프로그래머스
  • django
  • DFS
  • 다이나믹 프로그래밍
  • 백트래킹
  • boj
  • Network
  • docker
  • BFS
  • Kubernetes

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Henu

개발냥발

Algorithm/BOJ

[백준 1234] 크리스마스 트리 (C++)

2021. 10. 6. 17:37
 

1234번: 크리스마스 트리

첫째 줄에 트리의 크기 N, 빨강의 개수, 초록의 개수, 파랑의 개수가 주어진다. N은 10보다 작거나 같다. 빨강, 초록, 파랑의 개수는 0보다 크거나 같고, 100보다 작거나 같다.

www.acmicpc.net

 

레벨이 최대 10이므로 1 + ... + 10 = 55 이다.

따라서 한가지 색을 최대 55개까지만 사용할 수 있다. -> 배열의 크기가 [11][60][60][60]인 이유

 

cache 배열은 [현재 층][빨간색을 사용한 횟수][초록색을 사용한 횟수][파랑색을 사용한 횟수] = 경우의 수

 

기저조건은 재귀를 돌면서 현재 층이 N을 넘기면 해당 경우가 있다는 뜻으로 1을 반환하도록 했다.

 

각 층마다 사용된 색의 개수가 모두 같아야 하고, 각 층마다 색깔에 따라서 순열이 적용되므로 같은것이 포함된 순열의 경우의 수를 계산해 준다.

 

각 층마다 1가지 색만을 사용하는 경우 + 2가지 색깔을 사용하는 경우 + 3가지 모두 사용하는 경우를 더해서 현재 cache[][][][]값으로 정해준다.

 

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <cstring>
 
typedef long long ll;
using namespace std;
 
int N, R, G, B;
 
ll cache[11][60][60][60];
int fact[11];
 
int getFacto(int n){
    if(n == 0 || n == 1) return 1;
    if(fact[n]) return fact[n];
    return fact[n] = n * getFacto(n-1);
}
 
int numCase(int facto, int r, int g, int b){
    return facto / getFacto(r) / getFacto(g) / getFacto(b);
}
 
ll dfs(int lv, int r, int g, int b){
    if(lv > N) return 1;
    
    ll &ret = cache[lv][r][g][b];
    if(ret != -1) return ret;
    
    ret = 0;
    
    // 1가지 색 사용
    if(R - r >= lv) ret += dfs(lv+1, r+lv, g, b);
    if(G - g >= lv) ret += dfs(lv+1, r, g+lv, b);
    if(B - b >= lv) ret += dfs(lv+1, r, g, b+lv);
    
    // 2가지 색 사용
    if(lv % 2 == 0){
        if(R - r >= lv/2 && G - g >= lv/2){
            ret += (numCase(getFacto(lv), lv/2, lv/2, 0) * dfs(lv+1, r+lv/2, g+lv/2, b));
        }
        if(B - b >= lv/2 && G - g >= lv/2) {
            ret += (numCase(getFacto(lv), 0, lv/2, lv/2) * dfs(lv+1, r, g+lv/2, b+lv/2));
        }
        if(R - r >= lv/2 && B - b >= lv/2){
            ret += (numCase(getFacto(lv), lv/2, 0, lv/2) * dfs(lv+1, r+lv/2, g, b+lv/2));
        }
    }
    
    // 3가지 색 사용
    if(lv % 3 == 0 && R - r >= lv/3 && G - g >= lv/3 && B - b >= lv/3){
        ret += (numCase(getFacto(lv), lv/3, lv/3, lv/3) * dfs(lv+1, r+lv/3, g+lv/3, b+lv/3));
    }
    
    return ret;
}
 
int main(){
    cin >> N >> R >> G >> B;
    memset(cache, -1, sizeof(cache));
    cout << dfs(1, 0, 0, 0);
    
    return 0;
}
 
 
Colored by Color Scripter
cs

 

'Algorithm > BOJ' 카테고리의 다른 글

[백준 1103] 게임 (C++)  (0) 2021.10.10
[백준12762 ] 롤러코스터 (C++)  (0) 2021.10.06
[백준 2479] 경로찾기 (C++)  (0) 2021.09.29
[백준 16437] 양 구출 작전 (C++)  (0) 2021.09.28
[백준 15591] MooTube(Silver) (C++)  (0) 2021.09.28
    'Algorithm/BOJ' 카테고리의 다른 글
    • [백준 1103] 게임 (C++)
    • [백준12762 ] 롤러코스터 (C++)
    • [백준 2479] 경로찾기 (C++)
    • [백준 16437] 양 구출 작전 (C++)

    티스토리툴바