정리와기록 블로그

[9465] 스티커 본문

BOJ/동적계획법

[9465] 스티커

뫂림 2020. 3. 7. 15:18

문제: https://www.acmicpc.net/problem/9465

 

9465번: 스티커

문제 상근이의 여동생 상냥이는 문방구에서 스티커 2n개를 구매했다. 스티커는 그림 (a)와 같이 2행 n열로 배치되어 있다. 상냥이는 스티커를 이용해 책상을 꾸미려고 한다. 상냥이가 구매한 스티커의 품질은 매우 좋지 않다. 스티커 한 장을 떼면, 그 스티커와 변을 공유하는 스티커는 모두 찢어져서 사용할 수 없게 된다. 즉, 뗀 스티커의 왼쪽, 오른쪽, 위, 아래에 있는 스티커는 사용할 수 없게 된다. 모든 스티커를 붙일 수 없게된 상냥이는 각 스티커에 점

www.acmicpc.net

 

접근:

  • 다음 스티커를 선택하는 경우는 두 가지이다: 1) +1 대각선을 선택하는 경우, 2) +2 대각선을 선택하는 경우가 있다.
  • 이 두 경우 중 더 큰 값을 반환하는 경우를 선택한

  • 주의할 점은 (0,0), (1,0)을 0으로 두어야 시작부터 +1 경우와 +2 경우 모두 본다는 점이다.

 

코드:

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

using namespace std;
int N;
int arr[2][100001];
int cache[2][100001];

// y,x를 선택했을 때의 최대 값을 반환한다 
int getMax(int y, int x)
{
	if (x > N) return 0;
	
	int& ret = cache[y][x];
	if (ret != -1) return ret;

	int cand1 = arr[y][x], cand2 = arr[y][x];
	if (!y)
	{
		cand1 += getMax(y + 1, x + 1);
		cand2 += getMax(y + 1, x + 2);
	}
	else
	{
		cand1 += getMax(y - 1, x + 1);
		cand2 += getMax(y - 1, x + 2);
	}

	return ret = max(cand1, cand2);
}

int main()
{
	ios::sync_with_stdio(false);
	int T;
	cin >> T;

	while (T--)
	{
		memset(cache, -1, sizeof(cache));

		cin >> N;
		for (int i = 0; i < 2; i++)
			for (int j = 1; j <= N; j++)
				cin >> arr[i][j];

		cout << max(getMax(0, 0), getMax(1, 0)) << "\n";
	}			

	return 0;
}

'BOJ > 동적계획법' 카테고리의 다른 글

[11055] 가장 큰 증가 부분 수열  (0) 2020.03.07
[14002] 가장 긴 증가하는 부분 수열 4  (0) 2020.03.07
[2193] 이친수  (0) 2020.03.07
[16194] 카드 구매하기 2  (0) 2020.03.05
[15990] 1, 2, 3 더하기 5  (0) 2020.03.05
Comments