카테고리 없음

[백준 11501] - 주식(그리디?) C++

SeoburiFaust 2024. 3. 18. 17:01

문제

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

 

11501번: 주식

입력의 첫 줄에는 테스트케이스 수를 나타내는 자연수 T가 주어진다. 각 테스트케이스 별로 첫 줄에는 날의 수를 나타내는 자연수 N(2 ≤ N ≤ 1,000,000)이 주어지고, 둘째 줄에는 날 별 주가를 나타

www.acmicpc.net

접근방법

O(n*n)의 시간복잡도로는 해결하기 힘든 문제였다.

그리디 알고리즘이라고 생각하고 풀려고 했지만 잘 안 풀렸다.

 

결국 생각해낸 방법은 매수 매도 포인트를 미리 정해두는 것이다.

매일 하나씩 주식을 살 수 있으므로,

매도는 어차피 뒷 순서에 위치한 가장 큰 숫자에서 이루어질 수밖에 없다.

따라서 뒤에서부터 훑으며 매수 포인트와 매도 포인트를 구분할 수 있었다.

 

코드

//뒤에 보다 큰 숫자가 있는 경우 무조건 매수.
//뒤에 큰 숫자가 없다면 매수 X;
long long get_total(vector<int> price) {
    int maesu = -1, maesuCount = 0;
    long long total = 0;
    //매도 포인트 미리 지정.
    vector<bool> maesuPoint(price.size(), false);
    int tempPoint = price.size() - 1;
    for (int i = price.size() - 1;i > 0;i--) {
        if (price[tempPoint] > price[i-1]) {
            maesuPoint[i-1] = true;
        } else tempPoint = i-1;
    }
    FOR(i, price.size()) {
        if (maesuPoint[i]) {
            total -= price[i];
            maesuCount++;
        } else {
            total += (price[i] * maesuCount);
            maesuCount = 0;
        }
    }
    return total;
}

int t;
int main() {
    FASTERIO
    cin >> t;
    while(t--) {
        int n; long long answer;
        cin >> n;
        vector<int> price(n);
        FOR(i, n) {
            cin >> price[i];
        }
        cout << get_total(price) << "\n";
    }
    

    return 0;
}

개선할 점

테스트케이스가 좋아서 한 번에 맞출 수 있었다. 다행이다.

 

그래도 테스트케이스 한 개씩 직접 만들어서 해보고 제출하는 습관을 들이자.