Luo Gu P2365 task scheduling (optimized slope dp)

Portal

Ideas:
the most simple formula dp considered good: Let \ (dp (i, j) \) shows a front \ (i \) task, a total of \ (j \) minimum cost batch.
Then there is the transfer equation:
\ [DP (I, J) = min \ {DP (K, J-. 1) + (J * sumT_i + S) * (sumC_i sumC_k-) \} \]
why a \ (S * j \) , because the back of the batch will start in front of the answer affected.
But the complexity of the analysis is \ (O (n ^ 3) \) , certainly not.
Consider why the need for a second state? Is to eliminate the after-effect, because the latter does not know the total state started several times.
But we can put the cost calculated in advance , once activated, then for all subsequent machines will contribute, we advance this contribution forget, you can back up this matter, which is forced to eliminate after-effect .
Therefore converted \ (DP \) equation to as:
\ [DP (I) = min \ {DP (J) + sumT_i * (sumC_i-sumC_j) + S * (sumC_n-sum_j) \} \]
In fact, this Luo has been through the valley of the data, but not enough! We can also be optimized.
Observation \ (DP \) formula, followed by a portion of \ (i, j \)Product form-related variables, so we can consider the optimization of the slope dp.
The \ (i, j \) separation of variables, there are:
\ [DP (J) = (S + sumT_i) * + dp_i sumC_j sumC_i-S-sumT_i * * sumC_n \]
Obviously, this equation directly with a slope continuously maintains queue increased to the convex hull.
The time complexity of it is \ (O (n) \) a.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5005, MOD = 1e9 + 7;
int n, s;
int sumt[N], sumc[N];
int q[N], dp[N];
int main() {
#ifdef heyuhhh
    freopen("input.in", "r", stdin);
#else
    ios::sync_with_stdio(false); cin.tie(0);
#endif
    cin >> n >> s;
    for(int i = 1; i <= n; i++) {
        int t, c; cin >> t >> c;
        sumt[i] = sumt[i - 1] + t;
        sumc[i] = sumc[i - 1] + c;
    }
    int l = 1, r = 1; q[1] = 0;
    for(int i = 1; i <= n; i++) {
        while(l < r && dp[q[l + 1]] - dp[q[l]] <= (s + sumt[i]) * (sumc[q[l + 1]] - sumc[q[l]])) ++l;
        dp[i] = dp[q[l]] - sumt[i] * sumc[q[l]] - s * sumc[q[l]] + sumt[i] * sumc[i] + s * sumc[n];
        while(l < r && (dp[i] - dp[q[r]]) * (sumc[q[r]] - sumc[q[r - 1]]) <= (dp[q[r]] - dp[q[r - 1]]) * (sumc[i] - sumc[q[r]])) --r;
        q[++r] = i;
    }
    cout << dp[n];
    return 0;
}

Guess you like

Origin www.cnblogs.com/heyuhhh/p/11415406.html