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

Overview

VOI 2012 CROSS12 - Qua cầu

solution.md

Đầu tiên ta cần tính thời gian qua cầu của mỗi người (khi đi một mình). Có thể tính bằng tham lam như cách được sử dụng trong code ở trên hoặc kết hợp quy hoạch động với deque để tìm min trên đoạn tịnh tiến.

Độ phức tạp khi tính là \(O(m)\) cho mỗi người, vì \(r\) chỉ dao động từ 1 đến 100 nên ta dùng một mảng phụ để cache giá trị đã tính lại.

Sau khi tính xong, gọi thời gian qua cầu của \(n\) người là \(A(n)\), ta sắp xếp \(A\) tăng dần.

Gọi \(F(i)\) là thời gian ít nhất để những người từ 1 đến i qua cầu, ta có công thức:

\[F(1) = A(1) \\ F(2) = A(2) \\ F(i) = min \begin{cases} F(i-2) + A(1) + 2A(2) + A(i) & \quad (1)\\ F(i-1) + A(1) + A(i) & \quad (2)\\ \end{cases}\]

Trong trường hợp \((1)\), ta cho \(A(2)\) quay về, sau đó \(A(i)\) và \(A(i-1)\) qua cầu, sau đó \(A(1)\) từ bên kia cầu quay về, \(A(1)\) và \(A(2)\) cùng qua cầu.

Trong trường hợp \((2)\), \(A(1)\) quay về sau đó cùng \(A(i)\) qua cầu.

main.cpp
Open in Github Download
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int time(int r, int m, const char *bridge) {
    int i = 0, res = 1;
    while (i + r <= m) {
        res++;
        i += r;
        while (bridge[i] == '1') i--;
    }
    return res;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    int n, m; cin >> n >> m;
    vector<int> a(n);
    for (auto &x: a) cin >> x;
    string bridge; cin >> bridge;
    bridge = '0' + bridge + '0';
    vector<int> cache(101, 0);
    for (auto &x: a) {
        if (!cache[x]) x = cache[x] = time(x, m, bridge.data());
        else x = cache[x];
    }
    sort(a.begin(), a.end());
    if (n == 1) cout << a[0];
    else if (n == 2) cout << a[1];
    else {
        int f0 = a[0], f1 = a[1];
        for (int i=2; i<n; i++) {
            int f2 = min(f0 + a[0] + 2*a[1] + a[i], f1 + a[0] + a[i]);
            f0 = f1, f1 = f2;
        }
        cout << f1;
    }
    return 0;
}
Comments