This week's training topic is the DP Series. A classic series is the question of integrating stones.
(1) There are n piles of stones. Now we need to combine them into a pile of stones in sequence. The rule is as follows: we can only move two adjacent piles of stones to merge each time, the number of stones to be merged into the new one. Calculate the minimum (or maximum) Total Cost of combining the N stones into a pile ).
This is a simplified version of the stone merge, and the stone is in a row. It is found that only two adjacent stones can be merged. We will find that the greedy algorithm is ineffective here, and the local optimal solution cannot bring the overall optimal solution.
Therefore, it is not difficult to think that we should adopt the dynamic programing to find its optimal solution.
Dynamic Planning often uses the splitting of some of the overall optimal solutions to obtain the recursive formula of the optimal solution method. We can think of it as a combination of two piles of stones, therefore, the final optimal solution must be obtained by adding the sum of the two local optimal solutions.
Therefore, we can infer the dynamic transfer equation:
DP [I] [J] indicates the optimal solution from heap I to heap J. When I = J is, no addition exists, so the result is 0.
(2) Changing the above problem from a row to a ring is the issue of integrating the complete version of stones.
It is not difficult to find that the solution is similar. However, because it is a ring, we need to get the remainder of the number at each addition to prevent array overflow.
However, the meaning of J here is not the same as that of J in the previous section (1). The meaning of J here is: Starting from the I heap, count down the J heap stones. Therefore, when J = 0, DP [I] [J] = 0
Because J has different meanings, DP [I] [J] is naturally different. In fact, it is still a meaning.
Therefore, sum [I] [J] is also changed:
The code for finding the minimum value is attached:
1 # include <iostream> 2 # include <algorithm> 3 # include <limits> 4 using namespace STD; 5 const int INF = int_max; 6 const int maxn = 1003; 7 int DP [maxn] [maxn]; 8 int stone [maxn]; 9 int sum [maxn]; // 0-I and 10 int N; // number of 11 int getsum (int I, Int J) {12 if (I + j> = N) 13 return getsum (I, n-I-1) + getsum (0, I + J-N); 14 else15 return sum [I + J]-(I> 0? Sum [I-1]: 0); 16} 17 int findmin () {18 for (INT I = 0; I <n; I ++) {19 DP [I] [0] = 0; 20} 21 for (Int J = 1; j <n; j ++) {22 for (INT I = 0; I <n; I ++) {23 DP [I] [J] = inf; 24 25 for (int K = 0; k <j; k ++) {26 dp [I] [J] = min (DP [I] [J], DP [I] [k] + dp [(I + k + 1) % N] [J-k-1] + getsum (I, j); 27} 28} 29} 30 return DP [0] [n-1]; 31} 32 33 int main () {34 while (CIN> N) {35 for (INT I = 0; I <n; I ++) {36 CIN> stone [I]; 37 sum [I] = 0; 38} 39 sum [0] = stone [0]; 40 for (INT I = 1; I <n; I ++) {41 sum [I] = sum [I-1] + stone [I]; 42} 43 cout <findmin () <Endl; 44} 45 return 0; 46}
Vane_tse on the road. 10:04:43