Topic Links:
http://poj.org/problem?id=1738
Given n heap of stones, each time can only merge adjacent two piles of stone, each time the charge is the two piles of stone and;
Method One:
Interval DP complexity of O (n^3)
State transition equation
Dp[i][j]=min (Dp[i][k]+dp[k+1][j]+sup[i][j])
DP[I][J] represents the minimum cost of merging from I heap stones to the J heap of Stones, sum[i][j] represents from the I heap to the J Heap of Stones and
The code is as follows:
<span style= "FONT-SIZE:14PX;" > #include <iostream> #include <cstring> #include <cstdio>using namespace Std;const int maxn = 110; typedef long Long LL; LL SUM[MAXN]; LL DP[MAXN][MAXN]; LL A[maxn];int Main () {int n; while (~SCANF ("%d", &n)) {memset (sum,0,sizeof (sum)); for (int i=0;i<n;i++) {scanf ("%lld", &a[i]); if (i==0) sum[i]=a[i]; else Sum[i]=sum[i-1]+a[i]; } for (int i=0;i<maxn;i++) for (int j=i+1;j<maxn;j++) dp[i][j]=1000000000000000000; for (int len=2;len<=n;len++) {for (int i=0;i+len<=n;i++) {int j = i+len-1; for (int k=i;k<j;k++) {if (i==0) {dp[i][j]=min (Dp[i][k]+dp[k+1][j]+sum[j] , Dp[i][j]); printf ("dp[%d][%d]%d", i,k,dp[i][k]); printf ("dp[%d][%d]%d\n", k+1,j,dp[k+1][j]); cout<< "ans" <<dp[i][j]<<endl; } else Dp[i][j]=min (Dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1],dp[i][j]); }}} cout<<dp[0][n-1]<<endl; } return 0;} </span>
Method Two:
Garsiawachs algorithm
1) Set the stone sequence to st[], from left to right to find a minimum k to make a[k-1]<=a[k+1], merging K and K-1 Heap
2) then go left and find one of the biggest J make A[j]>a[k]+a[k-1] and put A[k-1]+a[k in his back
3) Repeat this operation until there is only a pile left.
Note: Set A[-1],a[n] as positive infinity
The code is as follows:
#include <iostream> #include <cstdio> #include <cstring>using namespace std;const int maxn = 50010;int Stone[maxn],n,t;int ret; void combine (int k) {int tmp = Stone[k] + stone[k-1]; RET +=tmp; for (int i=k; i<t-1; i++) {stone[i] = stone[i+1]; } t--; Int J; for (j=k-1; j>0 && stone[j-1]<tmp; j--) {stone[j] = stone[j-1]; } Stone[j] = tmp; while (j>=2 && stone[j]>=stone[j-2]) {int d = t-j; Combine (j-1); j = t-d; }}int Main () {while (scanf ("%d", &n), N) {for (int i=0; i<n; i++) scanf ("%d", stone+i); t=1,ret=0; for (int i=1; i<n; i++) {stone[t++] = Stone[i]; while (t>=3 && stone[t-3]<=stone[t-1]) {combine (t-2); }} while (t>1) combine (t-1); printf ("%d\n", ret); } return 0;}
Stone merging problem (naïve interval dp&&garsiawachs algorithm)