문제 출처
https://school.programmers.co.kr/learn/courses/30/lessons/258705
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제 설명
한 변의 길이가 1인 정삼각형 2n+1개를 이어붙여 윗변의 길이가 n, 아랫변의 길이가 n+1인 사다리꼴을 만들 수 있습니다. 이때 사다리꼴의 윗변과 변을 공유하는 n개의 정삼각형 중 일부의 위쪽에 같은 크기의 정삼각형을 붙여 새로운 모양을 만들었습니다. 예를 들어 n이 4이고, 1번째, 2번째, 4번째 정삼각형 위에 정삼각형을 붙인 모양은 다음과 같습니다.

이렇게 만든 모양을 정삼각형 타일 또는 정삼각형 2개를 이어 붙인 마름모 타일로 빈 곳이 없도록 채우려고 합니다. 정삼각형 타일과 마름모 타일은 돌려서 사용할 수 있습니다.

타일을 놓을 때 다른 타일과 겹치거나 모양을 벗어나게 놓을 수는 없습니다. 위의 예시 모양을 채우는 방법 중 일부는 다음과 같습니다.

사다리꼴의 윗변의 길이를 나타내는 정수 n과 사다리꼴 윗변에 붙인 정삼각형을 나타내는 1차원 정수 배열 tops가 매개변수로 주어집니다. 이때 문제 설명에 따라 만든 모양을 정삼각형 또는 마름모 타일로 빈 곳이 없도록 채우는 경우의 수를 10007로 나눈 나머지를 return 하도록 solution 함수를 완성해 주세요.
제한사항
- 1 ≤ n ≤ 100,000
- tops의 길이 = n
- tops[i]는 사다리꼴의 윗변과 변을 공유하는 i+1번째 정삼각형의 위쪽에 정삼각형을 붙이는 경우 1, 붙이지 않는 경우 0입니다.
입출력 예

입출력 예 설명
입출력 예 #1
문제의 예시와 같습니다. 문제에서 설명한 방법을 포함해 총 149가지 방법이 존재합니다.
따라서 149를 return 해야 합니다.
입출력 예 #2
문제 설명에 따라 만든 모양은 다음과 같습니다.

이 모양을 타일로 채우는 방법은 다음과 같이 총 11가지입니다.

따라서 11을 return 해야 합니다.
입출력 예 #3
경우의 수는 총 17,711가지입니다. 따라서 17711을 10007로 나눈 나머지인 7704를 return 해야 합니다.
풀이 방법
- 보자마자 dp 문제이겠거니 했는데, 점화식을 꺼내오는데 시간이 좀 걸렸다.
- 처음에 2n + 1의 삼각형이라 모양을 맞추어서 식을 유도해봤는데, 이러면 산이 있는 경우와 없는 경우에 대해 무작정 구해야하니 어려웠고... 블로그 글을 참조했다.
https://1eaf.site/cote/programmers_258705/
[Java]Programmers 산 모양 타일링(2024 KAKAO WINTER INTERNSHIP)
2024 KAKAO WINTER INTERNSHIP 산 모양 타일링 문제에 대한 해설입니다.
1eaf.site
- 해당 풀이처럼 삼각형을 세로열 기준으로 하나씩 나눠 풀이하였고...
이렇게 풀이하니 점화식이 다음과 같이 나왔다!
1. 위가 뾰족할때(산이 있을 때)
-> dp[i] = dp[i - 1] * 2 + dp[i - 2]
2. 위가 뾰족하지 않을 때(산이 없을 때)
-> dp[i] = dp[i - 1] + dp[i - 2]
- 다음과 같은 점화식을 얻었고, 코드를 쓰는 것은 쉬웠다...
풀이 코드
class Solution {
public int solution(int n, int[] tops) {
int k = 2 * n + 1;
int MOD = 10007;
int[] dp = new int[k + 1];
dp[0] = 1;
dp[1] = 1;
for(int i = 2; i <= k; i++){
//산모양인 경우
if(i % 2 == 0 && tops[(i - 1) / 2] == 1){
dp[i] = ((dp[i - 1] * 2) + dp[i - 2]) % MOD;
}
else {
dp[i] = (dp[i - 1] + dp[i - 2]) % MOD;
}
}
return dp[k];
}
}
결과

회고
- LV3만 되도 점화식이 많이 어려워지는구나... 싶었다.
자바스크립트 풀이 코드
- 점화식도 나와서 js버전으로도 풀어보았다!
function solution(n, tops) {
let MOD = 10007;
let k = 2 * n + 1;
let dp = new Array(k + 1).fill(0);
dp[0] = 1;
dp[1] = 1;
for(let i = 2; i <= k; i++){
if(i % 2 === 0 && tops[Math.floor((i - 1) / 2)] === 1){
dp[i] = ((dp[i - 1] * 2) + dp[i - 2]) % MOD;
}
else {
dp[i] = (dp[i - 1] + dp[i - 2]) % MOD;
}
}
return dp[k];
}
- 정수형이 따로 없어서, Math.floor를 통해 tops 내부만 정수로 만들면 별 차이 없었다.
자바스크립트 결과

'알고리즘' 카테고리의 다른 글
| [백준] 빙산 - Java (1) | 2025.03.20 |
|---|---|
| [프로그래머스] 오픈채팅방 - JavaScript (1) | 2025.03.20 |
| [백준] 타일 채우기 - Java (1) | 2025.03.19 |
| [프로그래머스] 프렌즈 4 블록 - JavaScript (1) | 2025.03.18 |
| [백준] 뱀 - Java (1) | 2025.03.17 |