Description
Input
Output
Sample Input
4
3 1 0 2
Sample Output
5
4
3
1
Data Constraint
Thinking
Not yet become superimposed Armor Armor 0:00 again, if you want to overlay armor, must not be superimposed together with the bad in the beginning.
Thus we can set a short DP, provided f [i] [j] represents the current i to stay in position and no power value, the current value of total consumed armor J,
. 1. 1-i ~ damage and have been tallied minimum injury and, then clearly there is f [i] [j] + c [i] [p] → f [i + p] [j + p] and f [i] [j] + a [i] → f [i + 1'd] [J], C
[i] [p] represents a superposition of p i in the armor i ~ i + p-1, and the damage, clearly c [i] [p] = c [i + 1] [p-1] + max (a [i] -p, 0), so
can O (n ^ 3) do.
Now consider how to optimize this first dp, transition is observed expression can be found each time f [i] [j] is transferred to f [i + p] [j + p], the state proceeds to
dimension and a second dimension the difference will not change, and then observe a nature that can be found C [IP] [P + J]> C = [I] J , according to a ij of the state of the packet,
then the removal of the second transfer, the transfer in for the same group, we look at the transfer coefficients, now consider f [i + d] [i ] and f [j + d] [j ]
of a f [d + z] [z ] of transfer (i > j) is better, see f [i + d] [i ] is shifted to f [i + d] [i ] + c [i + d] [zi] → f [d + z] [ z] and
f [j + d] [j ] + c [j + d] [zj] → f [d + z] [z], can be found as z increases, c [j + d] [ zj ] -c [i + value d] [zi] is gradually reduced, in simple terms,
that is, for a relatively small z, a f [i + d] [i ] more preferably transferred from, for larger z by f [j + d] [j ] transferred from better, we can
To maintain a monotonic stack to maintain optimal decision interval, updating the stack monotone, monotone decision requires a binary point, and therefore the complexity is O (2 ^ n-
log n-)
Code
#include <bits/stdc++.h>
#define F(i, a, b) for (int i = a; i <= b; i ++)
#define G(i, a, b) for (int i = a; i >= b; i --)
#define mem(a, b) memset(a, b, sizeof a)
#define mn(a, b) ((a) = min(a, b))
const int N = 4010;
using namespace std;
int n, TOT, sum, v, ans, G[N][N];
int a[2 * N], ct[N], C[N][N], Len[N], g[N][N], f[2 * N][N];
int main() {
freopen("griffin.in", "r", stdin);
freopen("griffin.out", "w", stdout);
scanf("%d", &n), Len[0] = 1, g[0][1] = 1e9;
F(i, 1, n) scanf("%d", &a[i]), Len[i] = 1, g[i][1] = 1e9;
F(i, 1, n) {
mem(ct, 0);
F(j, i, n)
if (a[j] + j - i <= n) ct[a[j] + j - i] ++;
C[i][0] = a[i], TOT = - ct[0], sum = 0;
F(j, 1, n) {
if (i + j - 1 <= n) TOT ++, sum += a[i + j - 1];
sum -= TOT, TOT -= ct[j], C[i][j] = sum;
}
}
mem(f, 7), f[0][0] = 0;
F(i, 0, n - 1) {
F(d, 0, 2 * n - i - 1)
mn(f[i + (d + 1)][i], f[i + d][i] + a[i + d + 1]);
if (i > 0) {
F(d, 0, n - i - 1) {
v = G[d][Len[d]];
if (f[i + d][i] >= f[v + d][v]) continue;
ans = i;
for (int l = i + 1, r = n; l <= r; ) {
int m = l + r >> 1;
if (f[i + d][i] + C[i + d + 1][m - i] < f[v + d][v] + C[v + d + 1][m - v])
ans = m, l = m + 1;
else
r = m - 1;
}
G[d][++ Len[d]] = i, g[d][Len[d]] = ans;
}
}
F(d, 0, 2 * n - i - 1) {
while (d < n && i + 1 > g[d][Len[d]]) Len[d] --;
v = d >= n ? 0 : G[d][Len[d]];
mn(f[(i + 1) + d][i + 1], f[v + d][v] + (v + d + 1 > n ? 0 : C[v + d + 1][i + 1 - v]));
}
}
F(i, 1, n) {
ans = 1e15;
F(k, n, n + n - 1)
ans = min(ans, f[k][i]);
printf("%d\n", ans);
}
}