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;
}
  |