※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 10067번 문제인 수열 나누기이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/10067
10067번: 수열 나누기
첫째 줄에 두 정수 n과 k가 주어진다. (2 ≤ n ≤ 100,000, 1 ≤ k ≤ min(n-1, 200)) 둘째 줄에는 수열을 나타내는 음이 아닌 정수 n개 a1, a2, ..., an이 주어진다. (0 ≤ ai ≤ 104)
www.acmicpc.net
주어진 배열을
주어진 배열(0-based index)의
위 식의 우변을 변형하면 다음과 같이 쓸 수 있다.
이 모든
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
#include <deque>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
ll N; int K;
deque<pair<pll, int>> dq;
ll total = 0;
ll psum[100000];
int backstep[201][100000];
ll dp[100000];
ll func(int idx, ll x) {
return dq[idx].first.first * x + dq[idx].first.second;
}
pair<ll, int> CHT1(ll x) {
while (dq.size() > 1) {
if (func(0, x) <= func(1, x)) dq.pop_front();
else break;
}
ll p = dq[0].first.first, q = dq[0].first.second;
return make_pair(p * x + q, dq[0].second);
}
void CHT2(ll a, ll b, int idx) {
while (!dq.empty()) {
int idx = dq.size() - 1;
ll p = dq[idx].first.first, q = dq[idx].first.second;
if (p < a) break;
if (b >= q) dq.pop_back();
else return;
}
while (dq.size() > 1) {
int idx1 = dq.size() - 1, idx2 = dq.size() - 2;
ll p1 = dq[idx1].first.first, q1 = dq[idx1].first.second;
ll p2 = dq[idx2].first.first, q2 = dq[idx2].first.second;
if ((q2 - b) * (a - p1) < (q1 - b) * (a - p2)) break;
dq.pop_back();
}
dq.push_back(make_pair(make_pair(a, b), idx));
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> K;
for (int i = 0; i < N; i++) cin >> psum[i];
for (int i = 1; i < N; i++) psum[i] += psum[i - 1];
for (int k = 1; k <= K; k++) {
dq.clear();
dq.push_back(make_pair(make_pair(0, 0), -1));
for (int i = 0; i < N; i++) {
pair<ll, int> ret = CHT1(psum[i]);
CHT2(psum[i], dp[i] - psum[i] * psum[i], i);
dp[i] = ret.first, backstep[k][i] = ret.second;
}
}
N--;
cout << dp[N] << '\n';
vector<int> ans;
for (int k = K; k > 0; k--) {
ans.emplace_back(backstep[k][N] + 1);
N = backstep[k][N];
}
while (!ans.empty()) {
cout << ans.back() << ' ';
ans.pop_back();
}
}
'BOJ' 카테고리의 다른 글
[BOJ 2878 // C++] 캔디캔디 (0) | 2023.06.17 |
---|---|
[BOJ 5254 // C++] Balls (0) | 2023.06.16 |
[BOJ 13230 // C++] Bits equalizer (0) | 2023.06.14 |
[BOJ 11334 // C++] Coin Turning Game (0) | 2023.06.13 |
[BOJ 13229 // C++] Selection Sum (0) | 2023.06.12 |