백준 9465번 스티커

honeyricecake·2022년 1월 16일
0

백준

목록 보기
8/30

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

고민의 흔적 ㅋㅋ

내가 짠 코드의 알고리즘

설명하자면 같은 줄은 두 칸 중 한칸이 최대니까
위를 땠을 때를 ox 아래를 땠을 때를 xo 둘다 안 땠을 때를 xx라 하고 스티커의 점수를 이차원 배열 array에 저장했을 때에 각 경우에 max[n]
(n번째 줄 스티커를 땠을 때 max값)을 구하는 알고리즘이다.

마지막엔 무조건 스티커를 떼야하므로
(안 떼는 경우의 점수보다 마지막에 떼는 경우가 무조건 더 높음)
마지막에 max ox 와 max xo만 비교하면 된다.

내 코드

#include <stdio.h>

int main()
{
	int T, n, i, j;
	int array[2][100000];
	int tempox, tempxo, tempxx, temp;
	scanf("%d", &T);
	for (i = 0; i < T; i++)
	{
		int maxox = 0;
		int maxxo = 0;
		int maxxx = 0;
		scanf("%d", &n);
		for (j = 0; j < n; j++)
		{
			scanf("%d", &array[0][j]);
		}
		for (j = 0; j < n; j++)
		{
			scanf("%d", &array[1][j]);
		}
		for (j = 0; j < n; j++)
		{
			tempox = maxox;
			tempxo = maxxo;
			tempxx = maxxx;//max값이 세개이므로 배열에 뒤집어 쓸 수가 없어서  tempox, tempxo, tempxx를 이용
			temp = tempxo > tempxx ? tempxo : tempxx;
			maxox = temp + array[0][j];
			temp = tempox > tempxx ? tempox : tempxx;
			maxxo = temp + array[1][j];
			maxxx = tempox > tempxo ? tempox : tempxo;
		}
		printf("%d\n", maxox > maxxo ? maxox : maxxo);
	}
	return 0;
}

다른 알고리즘

이 문제를 추천해준 친구 (https://www.acmicpc.net/user/rkaxhdals)의 알고리즘이다.
연산량이 나보다 적다.
(나는 최대 30만 이 알고리즘은 20만)
다만 걸리는 시간이 같은걸 보아 이 문제는 연산보다는 입출력에서 시간이 더 걸리는 듯하다.

스티커가 1줄이라 가정했을 때의 알고리즘과 성립함의 증명

스티커가 1줄이었을 때를 증명하였으므로 두 줄일 때는 직관적으로 훨씬 쉽게 와닿는다.

친구의 알고리즘으로 코드를 짰을 때 코드

#include <stdio.h>

int main()
{
	int i, j, T, n;
	int max[2][100002] = {0};
	scanf("%d", &T);
	for (i = 0; i < T; i++)
	{
		scanf("%d", &n);
		for (j = 0; j < n; j++)
		{
			scanf("%d", &max[0][j + 2]);
		}
		for (j = 0; j < n; j++)
		{
			scanf("%d", &max[1][j + 2]);
		}
		for (j = 0; j < n; j++)
		{
			max[0][j + 2] += max[1][j + 1] > max[1][j] ? max[1][j + 1] : max[1][j];
			max[1][j + 2] += max[0][j + 1] > max[0][j] ? max[0][j + 1] : max[0][j];
		}
		printf("%d\n", max[0][n + 1] > max[1][n + 1] ? max[0][n + 1] : max[1][n + 1]);
	}
	return 0;
}

0개의 댓글