From the past to the next DP;
Discretization first;
Assume that DP is at position I.
Las [I] indicates the last position of the I-th color.
T [k] indicates that the minimum subscript W (T [I], I) = K is satisfied, w (a, B) indicates that from a, A + 1, A + 2 ...... the number of different colors in the B interval.
Then, update the T array each time, and then update the DP array. K only needs to enumerate from 1 to SQRT (N), so the complexity is (N * SQRT (n )).
There are two situations when updating arrays.
1. if the front side of the color at the position I does not appear, all t [I] must be updated to for (Int J = up; j> = 1; j --) T [J + 1] = T [J], t [1] = I, up ++;
2. if the front side of the color at position I appears, you must update the T [I] section. You only need to update the T [I] of T [I]> las [A [I].
# Include <iostream> # include <cstdio> # include <cstring> # include <algorithm> # include <cmath> # include <map> # define INF 0x3f3f3fusing namespace STD; const int maxn = 50005; Map <int, int> MP; int CNT, N; int las [maxn], DP [maxn], a [maxn], t [250]; // las [I] indicates the position of the last I occurrence, and DP [I] indicates the minimum cost of the previous I. Int ID (int x) {If (! MP. count (x) MP [x] = ++ CNT; return MP [X];} void run () {MP. clear (); CNT = 0; For (INT I = 1; I <= N; I ++) {scanf ("% d", A + I ); A [I] = ID (A [I]);} memset (LAS, 0, sizeof las); int up = 1; t [1] = 1; DP [1] = 1; Las [A [1] = 1; for (INT I = 2; I <= N; I ++) {DP [I] = inf; If (! Las [A [I]) {for (Int J = up; j> = 1; j --) T [J + 1] = T [J]; if (up * up <= N) Up ++; t [1] = I;} else {int M = up; while (M & T [m] <= las [A [I]) m --; For (Int J = m-1; j> = 1; j --) T [J + 1] = T [J]; If (m) T [1] = I;} las [A [I] = I; for (Int J = 1; j * j <= I; j ++) {DP [I] = min (DP [I], DP [T [J]-1] + J * j);} printf ("% d \ n", DP [N]);} int main () {// freopen ("in", "r", stdin); While (scanf ("% d", & N)> 0) Run (); Return 0 ;}
HDU 5009 paint pearls (DP)