Interval DP.
Let's first give people numbers, numbered 1 to n from left to right.
For the whole interval, there must be a person who is the last to play, assuming that the last game is numbered S,
Because it is the order of the stack maintenance, then the number 1 to S-1 this S-1 individual, must be the first 1--s-1 to play (the specific order not known),
and the number s+1 to n these people must be the first s--n-1 to play (the specific order does not know).
Let's say we know the best solution for the people on the left and the right side,
We can deduce the optimal solution in the case of the last play of the number S.
How to calculate the optimal solution of an interval? You can design interval dp,dp[i][j] to represent the optimal solution for the group of people who are numbered I to J.
Suppose now to get dp[st][en] This interval optimal solution,
The optimal solution is: min{dp[st][s-1]+ (en-st) *a[s]+dp[s+1][en]+left* (Sum[en]-sum[s])}
Where S is the last person to enumerate, left indicates st--s-1 interval length
The dp[st][s-1] represents the best solution to the number of people on the left of the S-s-1, (en-st) *a[s] represents the price of S last play,
dp[s+1][en]+left* (Sum[en]-sum[s]) represents the optimal solution of S+1--en.
#include <cstdio>#include<cmath>#include<algorithm>#include<cstring>using namespacestd;Const intmaxn= -+Ten;intA[MAXN],SUM[MAXN];intDP[MAXN][MAXN];intT,n;voidRead () {scanf ("%d",&N); for(intI=1; i<=n;i++) scanf ("%d",&a[i]);}voidWork () { for(intI=1; i<=n;i++) for(intj=1; j<=n;j++) dp[i][j]=0x7FFFFFFF; memset (SUM,0,sizeofsum); for(intI=1; i<=n;i++) sum[i]=sum[i-1]+A[i]; for(intI=1; i<=n;i++) { for(intj=1; j<=n;j++) { intst=j,en=st+i-1;if(en>n)Continue; if(i==1) {dp[st][en]=0;Continue;} for(ints=st;s<=en;s++) { intleft=s-st,right=en-R; if(!left) dp[st][en]=min (Dp[st][en], dp[s+1][en]+a[s]* (I-1)); Else if(!right) dp[st][en]=min (Dp[st][en], dp[st][s-1]+a[s]* (I-1)); Elsedp[st][en]=min (Dp[st][en], dp[st][s-1]+Dp[s+1][en]+(i-1) *a[s]+ Left* (sum[en]-Sum[s])); }}} printf ("%d\n", dp[1][n]);}intMain () {intC=1; scanf ("%d",&T); while(t--) {read (); printf ("Case #%d:"C++); Work (); } return 0;}
HDU 4283 You is the one