문제 링크: https://www.acmicpc.net/problem/5463

 

IOI 2009 문제입니다. SWEA에 똑같은 문제가 있는데 풀이는 여기에 올려놨습니다.

SWEA에서는 맞았는데 백준에서는 틀렸다고 나와서 왜 그런지 몇시간동안 삽질을 하면서 원인을 찾아봤는데 원인은 배열 음수인덱스 접근때문이었습니다.

C++에서 배열 범위를 넘어가 접근하는 것은 Undefined Behavior이기 때문에 SWEA에서 운좋게(?) 통과가 됐었나봅니다. 이것때문에 몇 시간을 삽질했는지 후우;

#pragma GCC optimize ("Ofast")

#define _CRT_SECURE_NO_WARNINGS
#define _SILENCE_CXX17_C_HEADER_DEPRECATION_WARNING

#include <bits/stdc++.h>
using namespace std;


const int INF = INT_MAX;
const int MAX_LEN = 51;
const int MAX_VAL = 1000;

int cache[MAX_LEN][MAX_LEN][MAX_LEN][MAX_LEN];	// y, x, height, width
int chocolate[MAX_LEN][MAX_LEN];    // 초콜릿 한 칸당 위에 있는 건포도의 수
int c_sum[MAX_LEN][MAX_LEN];	// 누적합

inline int raisin_sum(int y, int x, int height, int width) {
	int y2 = y + height - 1,
		x2 = x + width - 1,
		y1 = y,
		x1 = x;

	int base = c_sum[y2][x2];
	if (y1 > 0) base -= c_sum[y1 - 1][x2];
	if (x1 > 0) base -= c_sum[y2][x1 - 1];
	if (y1 > 0 && x1 > 0) base += c_sum[y1 - 1][x1 - 1];

	return base;
}

inline int raisin_sum(int y, int x, int height, int width) {
	int y2 = y + height - 1,
		x2 = x + width - 1,
		y1 = y,
		x1 = x;

	return c_sum[y2][x2]
		- c_sum[y2][x1 - 1]
		- c_sum[y1 - 1][x2]
		+ c_sum[y1 - 1][x1 - 1];
}

int solve(int y, int x, int height, int width) {
	// base
	if (width == 1 && height == 1) return 0;

	int& ret = cache[y][x][height][width];
	if (ret != -1) return ret;
	ret = INF;


	const int base_raisins = raisin_sum(y, x, height, width);
	int best_payment = INF;

	// 가로로 자르기
	for (int cut_height = 1; cut_height < height; ++cut_height) {
		int payment = solve(y, x, cut_height, width) + solve(y + cut_height, x, height - cut_height, width);
		best_payment = min(best_payment, payment);
	}

	// 세로로 자르기
	for (int cut_width = 1; cut_width < width; ++cut_width) {
		int payment = solve(y, x, height, cut_width) + solve(y, x + cut_width, height, width - cut_width);
		best_payment = min(best_payment, payment);
	}

	return ret = best_payment + base_raisins;
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
#endif

	ios_base::sync_with_stdio(false);
	cin.tie(nullptr), cout.tie(nullptr);


	memset(cache, -1, sizeof(cache));

	int R, C;
	cin >> R >> C;

	assert(1 <= R && R <= MAX_LEN);
	assert(1 <= C && C <= MAX_LEN);

	for (int i = 0; i < R; ++i) {
		for (int j = 0; j < C; ++j) {
			cin >> chocolate[i][j];
			assert(0 <= chocolate[i][j] && chocolate[i][j] <= MAX_VAL);
		}
	}


	// 누적합 구하기
	for (int i = 0; i < R; ++i)
		for (int j = 0; j < C; ++j)
			c_sum[i][j] = (j == 0 ? chocolate[i][j] : c_sum[i][j - 1] + chocolate[i][j]);

	for (int i = 1; i < R; ++i)
		for (int j = 0; j < C; ++j)
			c_sum[i][j] = c_sum[i - 1][j] + c_sum[i][j];

	cout << solve(0, 0, R, C) << '\n';


	return 0;
}

앞으로는 귀찮아도 vector를 써야겠습니다. 후 몇시간이나 삽질을 한건지..

반응형

'Online Judge > 백준' 카테고리의 다른 글

[백준][C++] 1049: 기타줄  (0) 2020.08.08
[백준][C++] 5462: POI  (0) 2020.08.07
[백준][C++] 11051: 이항 계수 2  (0) 2020.08.05
[백준][C++] 11003: 최솟값 찾기  (0) 2020.08.04
[백준][C++] 5893: 17배  (0) 2020.08.03