Question: How to merge stones. DP problems.
Let's first consider the problem of a straight line. The minimum cost and the maximum cost are the same. We only consider one of them: Let's first consider a subproblem, to merge the stones from I to j into a heap, you must first merge them into two heaps. Since only two adjacent heaps can be merged, it must be that I to j is divided into two segments. If this center point is k, this scheme can be used to merge I to k first, and then merge k + 1 to j, however
After merging the two stacks, the cost of the last merge is the quality and of all stones from I to j. Therefore, we have dp [I; j] = min (dp [I; k] + dp [k + 1; j]) + weight [I; j], the O (N3) method is simply obtained.
If you want to consider the ring, you only need to select different headers in sequence, that is, split them into n different line segments.
[Cpp]
# Include <iostream>
# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <math. h>
# Include <vector>
# Include <queue>
# Include <algorithm>
Using namespace std;
# Define INF 0x3f3f3f
Int a [105];
Int dp [105] [105] [2];
Int n;
Int mmax, mmin;
Int weight (int I, int j)
{
Int sum = 0;
For (int k = I; k <= j; k ++) sum + = a [k];
Return sum;
}
Void solve ()
{
Memset (dp, 0, sizeof (dp ));
For (int I = n-1; I> = 1; I --)
{
For (int j = I + 1; j <= n; j ++)
{
Dp [I] [j] [0] =-INF, dp [I] [j] [1] = INF;
For (int k = I; k <j; k ++)
{
Dp [I] [j] [0] = max (dp [I] [j] [0], dp [I] [k] [0] + dp [k + 1] [j] [0] + weight (I, j ));
Dp [I] [j] [1] = min (dp [I] [j] [1], dp [I] [k] [1] + dp [k + 1] [j] [1] + weight (I, j ));
}
}
}
Mmax = max (mmax, dp [1] [n] [0]);
Mmin = min (mmin, dp [1] [n] [1]);
}
Int main ()
{
# Ifndef ONLINE_JUDGE
Freopen ("in.txt", "r", stdin );
# Endif
While (scanf ("% d", & n )! = EOF)
{
Mmax =-INF, mmin = INF;
For (int I = 1; I <= n; I ++) scanf ("% d", & a [I]);
Solve ();
For (int I = 2; I <= n; I ++)
{
Int last = a [1];
For (int I = 1; I <n; I ++) a [I] = a [I + 1];
A [n] = last;
Solve ();
}
Printf ("% d \ n", mmin );
Printf ("% d \ n", mmax );
}
Return 0;
}
# Include <iostream>
# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <math. h>
# Include <vector>
# Include <queue>
# Include <algorithm>
Using namespace std;
# Define INF 0x3f3f3f
Int a [105];
Int dp [105] [105] [2];
Int n;
Int mmax, mmin;
Int weight (int I, int j)
{
Int sum = 0;
For (int k = I; k <= j; k ++) sum + = a [k];
Return sum;
}
Void solve ()
{
Memset (dp, 0, sizeof (dp ));
For (int I = n-1; I> = 1; I --)
{
For (int j = I + 1; j <= n; j ++)
{
Dp [I] [j] [0] =-INF, dp [I] [j] [1] = INF;
For (int k = I; k <j; k ++)
{
Dp [I] [j] [0] = max (dp [I] [j] [0], dp [I] [k] [0] + dp [k + 1] [j] [0] + weight (I, j ));
Dp [I] [j] [1] = min (dp [I] [j] [1], dp [I] [k] [1] + dp [k + 1] [j] [1] + weight (I, j ));
}
}
}
Mmax = max (mmax, dp [1] [n] [0]);
Mmin = min (mmin, dp [1] [n] [1]);
}
Int main ()
{
# Ifndef ONLINE_JUDGE
Freopen ("in.txt", "r", stdin );
# Endif
While (scanf ("% d", & n )! = EOF)
{
Mmax =-INF, mmin = INF;
For (int I = 1; I <= n; I ++) scanf ("% d", & a [I]);
Solve ();
For (int I = 2; I <= n; I ++)
{
Int last = a [1];
For (int I = 1; I <n; I ++) a [I] = a [I + 1];
A [n] = last;
Solve ();
}
Printf ("% d \ n", mmin );
Printf ("% d \ n", mmax );
}
Return 0;
}