https://www.acmicpc.net/problem/2133
dp로 해결할 수 있는 문제
n = 1일때는 0이다.
n = 2 일때는 3이다. 아래 그림을 숫자로 표현하자면 (12, 34, 56), (13, 24, 56), (12, 35, 46)이다.
1 | 2 |
3 | 4 |
5 | 6 |
n = 3 일때는 0이다. 왜냐면 기본 블럭은 2개씩인데 n이 홀수 일때는 다 채울 수 없고 하나가 남기 때문이다.
1 | 2 | 3 |
4 | 5 | 6 |
7 | 8 | 9 |
따라서 n = 짝수 일때의 경우의 수를 구해보면 되는데 4일때도 한번 보자
1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
경우의 수가 생각보다 많다. 어떻게 계산해야할까
n = 2 일때 경우의 수가 하나더 옆에 있으니까 단순하게 3 * 3을 해서 구할 수 있을것같지만 23블럭이 하나로 합치는 경우도 생각해야한다. 그렇다면 1 x 2블록이 두개가 가운데에서 만났을때 2*1블로 두개로 대체할 수 있으니까. 3 * 3 + 2일 수도 있겠다. 우선 3 x 2 네모를 기본으로 하고 나머지를 계산해야한다.
dp를 이용한다면 dp[i]가 경우의 수이고 식을 세우자.
#include <iostream>
#include <algorithm>
#define MAX 31
using namespace std;
int dp[MAX] = { 0, };
int main(int argc, char* argv[])
{
int n;
cin >> n;
if (n % 2 == 1) {
cout << 0 << '\n';
return 0;
}
dp[0] = 1;
dp[1] = 0;
dp[2] = 3;
for (int i = 4;i <= n;i+=2) {
dp[i] = dp[i - 2] * dp[2];
for (int j = i - 4;j >= 0;j -= 2) {
dp[i] = dp[i] + (dp[j] * 2);
}
}
cout << dp[n] << '\n';
return 0;
}
'코딩테스트 > C++' 카테고리의 다른 글
[백준 C++] 3085번: 사탕 게임 (0) | 2024.05.14 |
---|---|
[백준 C++] 2309번: 일곱 난쟁이 (0) | 2024.05.14 |
[백준 C++] 13398번: 연속합 2 (0) | 2024.05.13 |
[백준 C++] 11054번: 가장 긴 바이토닉 부분 수열 (0) | 2024.05.13 |
[백준 C++] 11722번: 가장 긴 감소하는 부분 수열 (0) | 2024.05.13 |