1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
| // 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
struct Line { long long m, b; };
static inline __int128 eval128(const Line& l, long long x) {
return (__int128)l.m * x + l.b;
}
static inline bool isBad(const Line& l1, const Line& l2, const Line& l3) {
// (c2 - c1)/(m1 - m2) >= (c3 - c2)/(m2 - m3) → l2는 필요 없음
return (__int128)(l2.b - l1.b) * (l2.m - l3.m) >= (__int128)(l3.b - l2.b) * (l1.m - l2.m);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n; cin >> n;
vector<long long> a(n + 1), b(n + 1), dp(n + 1, 0);
for (int i = 1; i <= n; ++i) cin >> a[i];
for (int i = 1; i <= n; ++i) cin >> b[i];
// dp[i] = min_{j<i} (dp[j] + b[j] * a[i])
vector<Line> hull; hull.reserve(n);
hull.push_back({b[1], dp[1]});
int head = 0;
for (int i = 2; i <= n; ++i) {
while ((int)hull.size() - head >= 2 && eval128(hull[head], a[i]) >= eval128(hull[head + 1], a[i])) {
++head;
}
dp[i] = (long long)eval128(hull[head], a[i]);
Line cur{b[i], dp[i]};
while ((int)hull.size() - head >= 2 && isBad(hull[(int)hull.size() - 2], hull.back(), cur)) hull.pop_back();
hull.push_back(cur);
}
cout << dp[n] << '\n';
return 0;
}
|