알고리즘 풀이

[C#] 백준 9465번 문제풀이

bimtaeur30 2026. 3. 22. 14:53

문제번호: 9465

문제명: 스티커

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

문제내용과 예제 입/출력은 위 문제 링크에서 확인해 주시기 바랍니다

오늘은 스티커 떼어내기 DP 문제를 풀었습니다. 각 스티커에는 점수가 있고, 스티커를 떼어내면 위,아래,양옆 스티커가 홰손됩니다. 스티커가 붙은 데이터가 주어질 때, 스티커를 떼어내어 얻을 수 있는 최대 점수를 알아내야합니다.

우선 경우의 수는 다음과 같습니다.

1. 1번째 줄 뒤 스티커를 떼어낸다.
2. 2번째 줄 뒤 스티커를 떼어낸다.
3. 건너뛴다.

이를 통해 점화식을 만들어볼 수 있습니다.
위쪽 스티커와 아래쪽 스티커를 떼어가면서 점수를 누적시켜줍니다.

dp[0, k] = Math.Max(dp[1, k - 1], dp[1, k - 2]) + sticker[0, k];
dp[1, k] = Math.Max(dp[0, k - 1], dp[0, k - 2]) + sticker[1, k];

이후 dp의 끝줄에서 첫번째와 두번째줄 점수 중 더 큰것이 얻을 수 있는 최대점수가 됩니다.
다음은 정답코드입니다.

static void Main()
{
    using StreamReader sr = new StreamReader(Console.OpenStandardInput());
    using StreamWriter sw = new StreamWriter(Console.OpenStandardOutput());

    int T = int.Parse(sr.ReadLine()!);
    for (int i = 0; i < T; i++)
    {
        int n = int.Parse(sr.ReadLine()!);
        int[,] dp = new int[2, n];
        int[,] sticker = new int[2, n];


        for (int j = 0; j < 2; j++)
        {
            int[] stickers = Array.ConvertAll(sr.ReadLine().Split(), int.Parse);
            for (int k = 0; k < n; k++)
            {
                sticker[j, k] = stickers[k];
            }
        }

        dp[0, 0] = sticker[0, 0];
        dp[1, 0] = sticker[1, 0];

        if (n > 1)
        {
            dp[0, 1] = dp[1, 0] + sticker[0, 1];
            dp[1, 1] = dp[0, 0] + sticker[1, 1];

            for (int k = 2; k < n; k++)
            {
                dp[0, k] = Math.Max(dp[1, k - 1], dp[1, k - 2]) + sticker[0, k];
                dp[1, k] = Math.Max(dp[0, k - 1], dp[0, k - 2]) + sticker[1, k];
            }
        }


        sw.WriteLine(Math.Max(dp[0, n - 1], dp[1, n - 1]));
    }
}

'알고리즘 풀이' 카테고리의 다른 글

[C#] 백준 18870번 문제풀이  (0) 2026.03.25
[C#] 백준 1002번 문제풀이  (0) 2026.03.24
[C#] 백준 15311번 문제풀이  (0) 2026.03.21
[C#] 백준 33846번 문제풀이  (0) 2026.03.20
[C#] 백준 1697번 문제풀이  (0) 2026.03.18