본문 바로가기
PS/BOJ

백준 5463 / C++

by jaehoonChoi 2022. 8. 17.

https://www.acmicpc.net/problem/5463

 

5463번: 건포도

플로브디브의 유명한 초콜릿 가공업자 Bonny는 가로 M개, 세로 N개의 격자에 건포도들이 들어있는, N*M크기의 건포도 초콜릿을 만들었다. 각 1*1 격자에는 최소 1개 이상의 건포도가 들어있으며, 2개

www.acmicpc.net

 

[ 풀이 ]

나눴을 때 합을 계산해주려면 시작점 좌표와 끝점 좌표를 알아야 한다. 

마침 n,m도 50이하다. dp[sx][sy][ex][ey]를 (sx,sy)~(ex,ey)로 만들어지는 직사각형에서 건포도의 최소 양이라고 하자.

전이는 2가지다. 가로로 자르는 경우, 세로로 자르는 경우. 이후 식을 세우는건 쉬우므로 코드로 대체한다. 

 

[ Code ] 

#include <bits/stdc++.h>
using namespace std;
int n, m, psum[51][51], dp[51][51][51][51];

// (sx,sy)~(ex,ey) 누적합 
int sum(int sx, int sy, int ex, int ey) {
	return psum[ex][ey] - psum[ex][sy - 1] - psum[sx - 1][ey] + psum[sx - 1][sy - 1];
}

int go(int sx, int sy, int ex, int ey) {
	if (sx == ex && sy == ey) return 0;
	int& ret = dp[sx][sy][ex][ey];
	if (~ret)return ret;
	ret = 1e9;
	// 세로로 자름 
	for (int k = sy; k < ey; k++) {
		ret = min(ret, go(sx, sy, ex, k) + go(sx, k + 1, ex, ey) + sum(sx, sy, ex, ey));
	}
	// 가로로 자름 
	for (int s = sx; s < ex; s++) {
		ret = min(ret, go(sx, sy, s, ey) + go(s + 1, sy, ex, ey) + sum(sx, sy, ex, ey));
	}
	return ret;
}

int main() {
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> n >> m;
	memset(dp, -1, sizeof(dp));
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> psum[i][j];
			// 누적합 전처리 
			psum[i][j] += psum[i][j - 1] + psum[i - 1][j] - psum[i - 1][j - 1];
		}
	}
	cout << go(1, 1, n, m);
}

'PS > BOJ' 카테고리의 다른 글

백준 3037 / C++  (0) 2022.08.22
백준 1866 / C++  (0) 2022.08.18
백준 1017 / C++  (0) 2022.08.17
백준 9525 / C++  (0) 2022.08.17
백준 2191 / C++  (0) 2022.08.17

댓글