let menu = ["Home", "Algorithms", "CodeHub", "VNOI Statistics"];

Overview

MPILOT - Pilots

solution.md

Gọi F[i][j] là số tiền nhỏ nhất phải trả để thuê những người từ 1 đến i, trong đó có j người là lái chính.

Ta chỉ quan tâm đến các F[i][j] có \(0 \le j \le i / 2\), vì ngược lại thì cách thuê đó sẽ không hợp lệ.

Ban đầu, \(F[i][j] = +\infty\). Công thức QHĐ như sau:

\[F[0][0] = 0 \\ F[i][j] = \min \begin{cases} F[i - 1][j - 1] + X[i] \\ F[i - 1][j] + Y[i] \end{cases}\]

Kết quả cuối cùng là \(F[N][N / 2]\).

Độ phức tạp thời gian: \(O(n ^ 2)\)

Có thể cải tiến để đạt độ phức tạp không gian \(O(n)\) như code bên dưới.

main.cpp
Open in Github Download
#include <iostream>
#include <vector>
using namespace std;
#define ll long long

int main() {
    ios::sync_with_stdio(false); cin.tie(0);

    int n; cin >> n;
    vector<ll> x(n + 1), y(n + 1), f(n + 1, 1ll << 50);

    for (int i=1; i <= n; i++) cin >> x[i] >> y[i];

    f[0] = 0;
    for (int i=1; i <= n; i++) {
        for (int j = i / 2; j >= 1; j--) {
            f[j] = min(f[j] + y[i], f[j-1] + x[i]);
        }
        f[0] += y[i];
    }
    cout << f[n / 2];
}
Comments