알고리즘/문제 풀이

9465번: 스티커

Themion 2021. 12. 28. 17:24

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

 

9465번: 스티커

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스의 첫째 줄에는 n (1 ≤ n ≤ 100,000)이 주어진다. 다음 두 줄에는 n개의 정수가 주어지며, 각 정수는 그 위치에 해당하는 스티커의

www.acmicpc.net

한 열에 있는 스티커는 변을 공유하므로 같이 사용할 수 없고, 또 이웃한 열의 같은 행에 존재하는 스티커 역시 변을 공유하므로 사용할 수 없다. 따라서 i번째 열에서 선택 가능한 경우는 위쪽 스티커를 사용하는 것, 아래쪽 스티커를 사용하는 것, 스티커를 사용하지 않는 것 총 세 가지이다.

#include <iostream>

using namespace std;

#define MAX_N 100000

int max(int a, int b) { return a > b ? a : b; }

int test_case() {
    // 각 스티커의 가중치를 저장할 공간
    char stkr[2][MAX_N];
    // n: 스티커의 열의 개수, buf: 정수를 입력받아 char형 변수에 저장하기 위한 버퍼
    // ans[i % 2][j]: i번째 열까지에 대해 j에 해당하는 점수의 최댓값
    //  j -> 0: i번째 열의 스티커를 사용하지 않음
    //       1: i번째 열의 위쪽 스티커를 사용함
    //       2: i번째 열의 아랫쪽 스티커를 사용함
    int n, buf, ans[2][3] = {{ 0, }};

    // 문제의 조건을 입력받는다
    cin >> n;
    for (int i = 0; i < 2 * n; i++) {
        cin >> buf;
        stkr[i / n][i % n] = buf;
    }

    // 첫 번째 줄의 ans값을 저장한 뒤
    ans[0][1] = stkr[0][0]; ans[0][2] = stkr[1][0];

    // 두 번째 줄부터 모든 줄에 대해
    for(int i = 1; i < n; i++) {
        // 직전 값에서 현재 스티커를 사용 가능한 최댓값을 가져와 최댓값을 갱신
        ans[i % 2][0] = max(ans[!(i % 2)][1], ans[!(i % 2)][2]);
        ans[i % 2][1] = max(ans[!(i % 2)][0], ans[!(i % 2)][2]) + stkr[0][i];
        ans[i % 2][2] = max(ans[!(i % 2)][0], ans[!(i % 2)][1]) + stkr[1][i];
    }
    
    // 마지막 열의 스티커를 사용하지 않는 경우는 최댓값이 아니므로
    // 마지막 열의 스티커를 사용하는 두 경우 중 최댓값을 반환
    return max(ans[!(n % 2)][1], ans[!(n % 2)][2]);
}

int main() {
    // 입출력 속도 향상
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int T;
    // 테스트 케이스의 수를 입력받고 각 테스트 케이스를 실행
    for (cin >> T; T--; ) cout << test_case() << '\n';
    return 0;
}