3229: [Sdoi2008] Stone mergeDescriptionthere was a row of n piles of stones in a playground. It is now necessary to merge the stones into a pile in order. It is stipulated that each of the adjacent 2 stones can be merged into a new pile each time, and a new pile of stones is counted as the score of the merger. try to design an algorithm that calculates the minimum score to combine n heap stones into a pile. InputThe first line is a number n. The following n rows are a number a per line, representing the number of stones. Output
A total of one number, that is, n heap of stones combined into a pile of the smallest score.
Sample Input 4
1
1
1
1
Sample Output 8
HINT
For 100% of data, 1≤n≤40000
For 100% of data, 1≤a≤200
The following:
Personally think it's relatively simple (after knowing the GARSIAWACHS algorithm)
I only know the conclusion, set a sequence is a[0..n-1], each looking for the smallest one satisfies a[k-1]<=a[k+1] k, (for convenience set a[-1] and a[n] equals positive infinity)
then we merge A[k] with A[k-1] and then find the largest J that satisfies A[j]>a[k]+a[k-1], after which the combined value a[k]+a[k-1] is inserted into the a[j].
There is a theorem guaranteeing that the answer to the question will not change after this operation. As
an example:
186 103
because 35<103, so the smallest k is 3, we first remove 35 and 32, get them and 67, and look forward to a first more than 67 of the number, put 67 into his back
186 (K=3,a[3] and a[2] have been removed) 103
186 67 (hit the first right-to-left number than 67, we insert 67 behind him) 103
186 67 64 103 (there is a theorem guaranteeing that the answer to this sequence plus 67 equals the answer to the original sequence)
now from 5 numbers to 4 numbers, go on!
186 (k=2,67 and 64 were removed) 103
186 131 (just insert here) 103
186 131 103
now k=2 (Don't forget, set a[-1] and a[n] equals positive infinity)
234 186
420
What's the final answer? Is the sum of the weights of each merger. 420+234+131+67=852;
#include <stdio.h>#include <iostream>#include <algorithm>#include <string.h> using namespace std;const int max=2000000000; int n,i,j,k,m,ans,a[40005];int Main () {scanf ("%d",& N); for (i=1;i<=n;i++) scanf ("%d",&a[i]), a[0]=max; a[n+1]=Max; m=N; for (i=1;i<n;i++ {k=0; for (j=1;j<=m;j++) if (a[j-1]<=a[j+1]) {k=J; break;} a[k-1]+=a[k]; for (j=k;j<m;j++) a[j]=a[j+1]; k--; ans+=a[k]; while (k>0&&a[k-1]<=a[k]) {Swap (A[k-1],a[k]); k--;} a[m]=Max; m--;} cout<<ans; return 0;}
3229: [Sdoi2008] Stone merge