유명한 DP 문제 2 x N 타일링의 업그레이드 버전
이젠 세로의 길이가 2가 아니라 3이다!!
DP 공식을 잘 유도하면 쉽게 풀 수 있다!!
자세한 문제 설명과 제한 사항은 프로그래머스 홈페이지 참고. 문제풀러가기
dp 공식을 유도해야하는데 순서대로 잘 그려보면 알 수 있다.
일단 n이 홀수면 타일링을 할 수 없으므로 답은 0 이다.
그려보면
n 이 4일 때를 생각해보자.
(ㅣ = ㅣ 이런식으로 가운데 가로 타일을 놓는 것)
n 이 6일 때를 생각해보자.
(3X4 에는 3X2와 3X2로 만들 수 있는 모든 경우의 수가 포함되어 있다.)
왜냐하면 3X4 타일링의 방법의 수 * 3X2 타일링의 방법의 수를 할 때 오른쪽 4칸을 포함하는 오직 3X4만이 만들 수 있는 2가지 경우의 수는 들어가있지 않기 때문이다.
n 이 8 일 때는
감이 오는가?? 3XN 을 타일링 할 때는
다시 말하면
프로그래머스 사이트가 아닌, visual studio 에서 코드를 작성해서 그대로 가져온 것 입니다. 일부 테스트 코드가 존재합니다.
#include <string>
#include <vector>
using namespace std;
//풀이
//ex n = 8
//더해야할 것
//answer(6) * answer(2)
//answer(2) * 2 (n 이 6일때만 존재하는 2개의 경우)
//answer(4) * 2 (n 이 4일때만 존재하는 2개의 경우)
//dp1의 인덱스는0 부터 시작되며 n이 2씩 증가할 때 마다의 값이 저장됨 n이 2,4,6,8 ....일 때
//dp2는 인덱스 0 부터 인덱스 n - 2 까지의 각각의 값 *2 의 합이 저장.
long long dp1[4096];
long long dp2[4096];
int solution(int n);
int main() {
solution(16);
}
int solution(int n) {
if (n % 2 == 1)
return 0;
dp1[0] = 3;
dp1[1] = 11;
dp2[1] = 6;
for (int i = 2; i < n / 2; i++) {
dp1[i] = (dp1[i - 1] * 3 + dp2[i - 1] + 2) % 1000000007;
dp2[i] = (dp1[i - 1] * 2 + dp2[i - 1]) % 1000000007;
}
return dp1[n / 2 - 1];
}
디피는 어렵다. 단순한 문제 일 수록 더욱 어렵다.
생각을 많이하고 시간을 많이 소요하는 문제들도 생각보다 많다.
화이팅!