The problem of ring gravel merging (dynamic programming)
The traditional problem of gravel merging is: There are n heaps of stones, the stones are ordered to be merged into a pile, as follows: Each time you can only move adjacent 2 piles of gravel, combined with the number of newly synthesized piles of stone, the total cost of this n-heap is the smallest (or largest).
Such problems are similar to the solution of the interval DP, set DP[I][J] to merge the minimum total cost from I to J, then preprocessing the prefix and the transfer equation is Dp[i][j]=max (dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]), and the I==j DP I [J]=0; core code is:
for (int v. = 1; v < n; v++)
{for
(int i = 0;i < n-v; i++)
{
Int j = i + V;
DP[I][J] = INF;
int tmp = Sum[j]-(i > 0 sum[i-1]:0);
for (int k = i; k < J; k++)
dp[i][j] = min (Dp[i][j], dp[i][k] + dp[k+1][j] + tmp);
}
The problem of ring gravel merging is Logu P1880 topic description
In a circular playground around the n heap of stones, now to the stone in order to merge into a pile. Specify that only adjacent 2 stacks can be merged into a new pile at a time, and a new pile of stones will be counted as the combined score.
1 algorithms were designed to calculate the minimum and maximum scores of n-heap stones combined into 1 piles. Input output Format input format:
The 1th row of the data is a positive integer n,1≤n≤100, indicating that there are n heaps of stones. The 2nd row has n numbers, representing the number of stones per heap.
Output format:
Output a total of 2 lines, the 1th behavior minimum score, the 2nd behavior maximum score. Input and Output sample input sample #:
4
4 5 9 4
Output Sample #:
54
Solution: The typical way to handle a ring is to break the loop into a chain, that is to enlarge the length by twice times, the best score for the chain can be reversed by enumerating the left endpoint and then finding the best of the current to the right endpoint, because the chain is twice times the length, so it should be enumerated from the 2*n-1, each time the length of n is enumerated, Then you can find the final answer from 1-n.
AC Code:
#include <iostream> #include <algorithm> using namespace std;
#define _FOR (I,A,B) for (int i=a;i<=b;i++) const int MAXN = 507;
const int inf = 0X3F3F3F;
int N,M,A[MAXN],SUM[MAXN],DP_MAX[MAXN][MAXN],DP_MIN[MAXN][MAXN];
int main (int argc, char const *argv[]) {cin>>n;
_for (i,1,n) {cin>>a[i];
Sum[i]=sum[i-1]+a[i];
} _for (i,n+1,n*2) {a[i]=a[i-n];
Sum[i]=sum[i-1]+a[i];
for (int i=n*2-1;i>0;i--) {_for (j,i+1,i+n) {dp_min[i][j]=inf;
_for (k,i,j-1) {dp_min[i][j]=min (dp_min[i][j],dp_min[i][k]+dp_min[k+1][j]+sum[j]-sum[i-1]);
Dp_max[i][j]=max (Dp_max[i][j],dp_max[i][k]+dp_max[k+1][j]+sum[j]-sum[i-1]);
'} ' int ans_min = INF;
int Ans_max = 0;
_for (i,1,n) {Ans_max=max (Dp_max[i][i+n-1],ans_max);
Ans_min=min (dp_min[i][i+n-1],ans_min); } Cout<<ans_min<<endl;
cout<<ans_max<<endl;
return 0; }