Algorithm

[algospot] 폴리오미노 (c++)

salmon16 2021. 4. 1. 14:48

풀이 방법

dp 문제인데 문제를 부분 문제로 나누기 어려운 문제 였다.

처음에는 정사각형 하나를 두고 상하좌우로 사각형을 붙이는 형태로 부분 문제를 쪼개려고 생각 했지만 이러면 중복되는 부분을 다 제거 하기가 복잡해서 실패 했다.

정답은 층별로 부분 문제를 쪼개는 것이다 재귀 함수로 현재 남은 상자수와 각 재귀마다 첫 층에 쓸 상자수를 보내주고 

함수 안에서 for 문을 돌며 2번째 층에는 몇개의 상자를 사용할지 선택후 함수 리턴값을 더하면 된다

여기서 리턴값에 first + second - 1를 곱해주어야 한다 1층과 2층을 한 칸씩 옆으로 이동시키면 다른 경우가 되기 때문이다. 시간 복잡도는 O(n^3)이다.

#include <iostream>
#include <algorithm>
#include <memory.h> 
#include <vector>

const int MOD = 10000000;
using namespace std;

int dp[101][101];

int f(int n, int first) {
    if (n == first) return 1;
    int& ret = dp[n][first];
    if (ret != -1) return ret;
    ret = 0;
    for (int i = 1; i <= n - first; i++) {
        int add = i + first - 1;
        add *= f(n - first, i);
        add %= MOD;
        ret += add;
        ret %= MOD;
    }
    return ret;
}

int main(void) {
    int C;
    cin >> C;        
    while (C--) {
    	memset(dp, -1, sizeof(dp));
        int num;
        cin >> num;
        int count = 0;
        for (int i = 1; i <= num; i++) {
            count += f(num, i);            
            count %= MOD;
        }
        cout << count << endl;
    }
    return 0;
}

 

'Algorithm' 카테고리의 다른 글

[algospot] Quantization (c++)  (0) 2021.04.02
[백준] 설탕 2839번 (c++)  (0) 2021.04.02
[백준] 가장 큰 정사각형 1915번 (c++)  (0) 2021.03.31
[학교 과제] 프리랜서 (c++)  (0) 2021.03.30
[학교 과제] 카드덱 (c++)  (0) 2021.03.30