Official

F - Sensor Optimization Dilemma Editorial by en_translator


Consider solving the problem using DP (Dynamic Programming). One of the easiest ones to come up with may be one that maintains “how many sensor \(1\) was used?” and “how many sensor \(2\) was used?” as keys, but this does not finish in the execution time limit. Instead, when the number of sensor \(1\) used so far is fixed, we only have to consider the minimum use of sensor \(2\), so we can naturally derive the following DP:

\[dp[i][j] = (\text{the minimum number of sensor }2\text{ required to cover the first }i\text{ segments, when sensor }1\text{ is used }j\text{ times}).\]

The transition can be derived by considering how many sensor \(1\) should be used to cover the \(i\)-th segment:

\[dp[i][j] = \max_{0 \leq k \leq j} \bigg(dp[i-1][j-k] + \Big\lceil \frac{\max(D_i-kL_1,0)}{L_2} \Big\rceil \bigg).\]

Since there are \(O(NK_1)\) states, and a transition costs \(O(K_1)\), so the overall complexity is \(O(NK_1^2)\), which is fast enough.

Sample code (C++):

#include<bits/stdc++.h>

using namespace std;

using ll = long long;

int main() {
    int n;
    cin >> n;
    vector<int> d(n);
    for (int &i: d) cin >> i;
    vector<int> l(2), c(2), k(2);
    for (int i = 0; i < 2; i++) {
        cin >> l[i] >> c[i] >> k[i];
    }
    vector dp(n + 1, vector<int>(k[0] + 1, 1e9));
    dp[0][0] = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j <= k[0]; j++) {
            int rem = d[i];
            for (int nj = j; nj <= k[0]; nj++) {
                dp[i + 1][nj] = min(dp[i + 1][nj], dp[i][j] + (rem + l[1] - 1) / l[1]);
                rem = max(rem - l[0], 0);
            }
        }
    }
    ll ans = 2e18;
    for (int i = 0; i <= k[0]; i++) {
        if (dp[n][i] > k[1]) continue;
        ans = min(ans, (ll) c[0] * i + (ll) c[1] * dp[n][i]);
    }
    if (ans > 1e18) ans = -1;
    cout << ans << endl;
}

posted:
last update: