※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 11501번 문제인 주식이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/11501
11501번: 주식
입력의 첫 줄에는 테스트케이스 수를 나타내는 자연수 T가 주어진다. 각 테스트케이스 별로 첫 줄에는 날의 수를 나타내는 자연수 N(2 ≤ N ≤ 1,000,000)이 주어지고, 둘째 줄에는 날 별 주가를 나타
www.acmicpc.net
각 날에 대하여 이후의 날 중 그 날보다 주식의 가격이 더 높은 날이 있다면 그 주식을 구입해 앞으로 다가올 날 중 가장 주식이 비싼 날에 판매하는 것이 그 날의 주식으로 얻을 수 있는 최대의 이득임을 관찰하자.
한편, 주식을 구입하지 않는 것은 주식을 구입 후 당일에 바로 파는 것과 같게 생각할 수 있음을 관찰하자. 이 관찰을 적용하면 주어진 문제를 각 주식에 대하여 (당일을 포함한) 앞으로 가장 비쌀 가격에 주식을 팔아 얻을 수 있는 총 이득을 계산하는 것으로 해결할 수 있게 된다.
해당 날을 포함한 이후 날에 주식의 가장 비싼 가격을 날짜를 시간역순으로 살펴나가 구해나가면서 문제를 해결해주자.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
int T, N;
ll arr[1000000];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> T;
while (T--) {
ll ans = 0;
cin >> N;
for (int i = 0; i < N; i++) cin >> arr[i];
ll mx = 0;
for (int i = N - 1; i > -1; i--) {
mx = max(mx, arr[i]);
ans += mx - arr[i];
}
cout << ans << '\n';
}
}
여담으로, 글쓴이는 처음에는 monotone stack을 이용하여 문제를 해결하였다. 아래는 해당 코드이다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
int T, N;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> T;
while (T--) {
cin >> N;
vector<pair<ll, pair<ll, ll>>> vec; // {주식값, {누적주식값, 누적주식개수}}
while (N--) {
ll x; cin >> x;
ll psum = x, pcnt = 1;
while (!vec.empty() && vec.back().first < x) {
psum += vec.back().second.first, pcnt += vec.back().second.second;
vec.pop_back();
}
vec.emplace_back(make_pair(x, make_pair(psum, pcnt)));
}
ll ans = 0;
while (!vec.empty()) {
ans += vec.back().second.second * vec.back().first - vec.back().second.first;
vec.pop_back();
}
cout << ans << '\n';
}
}
'BOJ' 카테고리의 다른 글
[BOJ 3188 // C++] nule (0) | 2023.10.08 |
---|---|
[BOJ 3185 // C++] kviz (0) | 2023.10.07 |
[BOJ 9079 // C++] 동전 게임 (1) | 2023.10.05 |
[BOJ 9078 // C++] 정렬 (1) | 2023.10.04 |
[BOJ 2016 // C++] 미팅 주선하기 (0) | 2023.10.03 |