반응형

문제풀이:www.acmicpc.net/problem/1577

 

1577번: 도로의 개수

첫째 줄에 도로의 가로 크기 N과 세로 크기 M이 주어진다. N과 M은 100보다 작거나 같은 자연수이고, 둘째 줄에는 공사중인 도로의 개수 K가 주어진다. K는 0보다 크거나 같고, 100보다 작거나 같은

www.acmicpc.net

 

특이한 dp 문제입니다. 

일반적으로 0,0에서 n,m으로 이동할때 2방향으로만 이동가능하다면 

dp[i][j] = dp[i-1][j] + dp[i][j-1] 입니다.

 

하지만 이문제에서는 이동할 수 없는 구간들이 있습니다. 

 

그렇기 때문에 이러한 부분은 표시해주어야 합니다.

저는 bool construction[201][201] 배열을 통해서 해결했습니다.

construction[b+d][a+c] = 1 값을 저장해주면서 진행했습니다.

 

이때 dp[i][j]는 

 

if (construction[2 * i - 1][2 * j] == 0)
   dp[i][j] += dp[i - 1][j];
if (construction[2 * i][2 * j - 1] == 0)
   dp[i][j] += dp[i][j - 1];

 

입니다.

 

 

아래는 정답코드입니다.

#include <iostream>
using namespace std;

int n = 0, m = 0, k = 0;
int a, b, c, d;
bool construction[201][201] = { 0, };
unsigned long long dp[101][101] = { 0, };
int y_ar[2] = { 0,-1 };
int x_ar[2] = { -1,0 };
int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	cin >> n >> m;
	cin >> k;

	for (int i = 0; i < k; i++) {
		cin >> a >> b >> c >> d;
		construction[b + d][a + c] = 1;
	}
	dp[0][0] = 1;

	for (int i = 1; i <= m; i++) {
		if (construction[2 * i - 1][0] == 1)
			break;
		dp[i][0] = 1;
	}
	for (int i = 1; i <= n; i++) {
		if (construction[0][2 * i - 1] == 1)
			break;
		dp[0][i] = 1;
	}


	for (int i = 1; i <= m; i++) {
		for (int j = 1; j <= n; j++) {
			if (construction[2 * i - 1][2 * j] == 0)
				dp[i][j] += dp[i - 1][j];
			if (construction[2 * i][2 * j - 1] == 0)
				dp[i][j] += dp[i][j - 1];


		}
	}

	cout << dp[m][n] << endl;
	return 0;
}
반응형

'알고리즘 > DP' 카테고리의 다른 글

[백준] 9252-LCS 2(C++)  (0) 2021.01.05
[백준] 5502-팰린드롬(C++)  (0) 2021.01.05
[백준] 1301-비즈 공예(C++)  (0) 2021.01.01
[백준] 2411-아이템 먹기(C++)  (0) 2020.12.31
[백준] 11054-가장 긴 바이토닉 부분 수열(C++)  (0) 2020.12.30

+ Recent posts