문제 링크


www.acmicpc.net/problem/20544

 

20544번: 공룡게임

크롬 브라우저 상에서 인터넷 연결이 안될때나, 주소창에 chrome://dino 를 입력하면 공룡 게임을 플레이 할 수 있다.

www.acmicpc.net

 

접근 방법

 


 해당문제는 4차원 DP를 사용하여 해결 할 수 있었습니다. 1차원 좌표계에서 4차원 DP를 생각해내는 것이 쉬운 일은 아니었던 문제였습니다.

 

DP의 1~4차원을 설명하자면

1. 현재 위치

2. 현재 높이(0,1,2) 

3. 과거 높이(0,1,2)

4. 높이가 2인 장애물 포함 여부(0,1)

 

 일단 문제를 처음 접근할 때 현재위치와 현재높이를 포함한 DP를 설계해야겠다고 생각했습니다. 이 후 과거의 높이가 다음의 높이 값에 영향을 줄 수 있는 변수라는 것을 알았습니다. 

예를 들어 현재의 값만 생각하였을 때 현재 상태가 1이라면 다음 상태는 0, 1, 2중 어떤 값이 와도 상관이 없습니다. 하지만 과거의 값이 1이었다면 다음 값은 0으로만 갈 수 있게 됩니다.

 

 또한 [현재위치][현재높이][과거높이]가 중복되는 값이 나오더라도 장애물 2를 포함해서 오지 않았다면 다른 경우의 수가 된다는 것을 떠올릴 수 있었습니다. 즉 DP에 장애물 2를 포함했는지의 여부를 나타내는 차원을 추가하였습니다.

 

소스 코드


#include<iostream>
#include<algorithm>
#include<string.h>

using namespace std;
long long dp[1001][3][3][2];
long long mod = 1000000007;
int N;

long long solve(int now, int state, bool flag, int laststate) {

	long long &ref = dp[now][state][laststate][flag];

	if (now == N - 1) {
		if (flag)
			return ref = 1;
		else
			return ref;
	}	
	if (ref != 0)
		return ref;
	
	if (state == 0) {
		ref += solve(now + 1, 0, flag, state) % mod;
		ref += solve(now + 1, 1, flag, state) % mod;
		ref += solve(now + 1, 2, true, state) % mod;
	}
	else if (state == 1) {
		if (laststate == 0) {
			ref += solve(now + 1, 0, flag, state) % mod;
			ref += solve(now + 1, 1, flag, state) % mod;
			ref += solve(now + 1, 2, true, state) % mod;
		}
		else {
			ref += solve(now + 1, 0, flag, state) % mod;
		}
	}
	else if(state == 2){
		if (laststate == 0) {
			ref += solve(now + 1, 0, flag, state) % mod;
			ref += solve(now + 1, 1, flag, state) % mod;
		}
		else {
			ref += solve(now + 1, 0, flag, state) % mod;
		}
	}
	return ref = ref % mod;
}

int main() {

	ios_base::sync_with_stdio(false);
	cout.tie(0);
	cin.tie(0);

	cin >> N;

	cout << solve(0, 0, false, 0) << "\n";

}

 

+ Recent posts