Problem-solving: DP... is actually to first convert this line into a segment with a length of 1 and then into a segment with a length of 2 ........ Optimal sub-structure .... Spell out the optimal solution of 0-n-1
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <vector> 6 #include <climits> 7 #include <algorithm> 8 #include <cmath> 9 #define LL long long10 using namespace std;11 int d[210],dp[210][210],sum[210];12 int main() {13 int i,j,n,k,v,add;14 while(~scanf("%d",&n)) {15 memset(dp,0,sizeof(dp));16 for(add = i = 0; i < n; i++) {17 scanf("%d",d+i);18 add += d[i];19 sum[i] = add;20 }21 for(v = 1; v < n; v++) {22 for(i = 0; i < n-v; i++) {23 j = i+v;24 dp[i][j] = INT_MAX;25 add = sum[j] - (i?sum[i-1]:0);26 for(k = i; k < j; k++) {27 dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+add);28 }29 }30 }31 printf("%d\n",dp[0][n-1]);32 }33 return 0;34 }View code
Convert an O (nlogn) algorithm: garsiawachs algorithm. This algorithm is too embarrassing. Please use it with caution... Pai_^
The procedure is as follows:
Set the sequence to stone [], from left to right, find a k that satisfies stone [k-1] <= stone [k + 1, after finding and merging stone [k] and stone [k-1], find the largest J from the current position to the left, make it fit stone [J]> stone [k] + stone [k-1], just insert it behind J. Repeat until there is only one pile of stones left. In this process, we can assume that stone [-1] and stone [N] are infinite.
For example:
186 64 35 32 103
Because 35 <103, so the minimum K is 3, we first Delete 35 and 32, get their and 67, and look forward to a number that exceeds 67, insert 67 to the end and get: 186 67 64 103. Now the number is changed from 5 to 4. Continue: 186 131 103. Now K = 2 (don't forget, if a [-1] and a [n] are equal to positive infinity, 234 186 is obtained. What is the final answer? Is the sum of the Combined Weights, that is, 420 + 234 + 131 + 67 = 852.
The basic idea is to obtain the depth constraint between nodes through the optimization of the tree, and then prove that the solution after one operation can correspond to the original solution one by one, make sure that the depth of the node does not change after it is moved. The specific implementation of this algorithm requires a little skill. The essence is to constantly and quickly find the minimum K, that is, to maintain a "2-decreasing sequence", the time complexity of simple implementation is O (n * n ), however, a balance tree can be used for optimization, so that the final complexity is O (nlogn ).
1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 5 using namespace std; 6 const int N = 50005; 7 8 int stone[N]; 9 int n,t,ans;10 11 void combine(int k)12 {13 int tmp = stone[k] + stone[k-1];14 ans += tmp;15 for(int i=k;i<t-1;i++)16 stone[i] = stone[i+1];17 t--;18 int j = 0;19 for(j=k-1;j>0 && stone[j-1] < tmp;j--)20 stone[j] = stone[j-1];21 stone[j] = tmp;22 while(j >= 2 && stone[j] >= stone[j-2])23 {24 int d = t - j;25 combine(j-1);26 j = t - d;27 }28 }29 30 int main()31 {32 while(scanf("%d",&n)!=EOF)33 {34 if(n == 0) break;35 for(int i=0;i<n;i++)36 scanf("%d",stone+i);37 t = 1;38 ans = 0;39 for(int i=1;i<n;i++)40 {41 stone[t++] = stone[i];42 while(t >= 3 && stone[t-3] <= stone[t-1])43 combine(t-2);44 }45 while(t > 1) combine(t-1);46 printf("%d\n",ans);47 }48 return 0;49 }View code
Code seems a headache... So I had... I wrote a frustrated code, and it is estimated that the coefficient is large .. So it is slower than the above Code, but compared... DP... That's much faster .....
1 #include <iostream> 2 #include <cstdio> 3 #include <climits> 4 using namespace std; 5 int d[50010],n; 6 int main() { 7 int i,j,ans,temp; 8 while((~scanf("%d",&n))&&n) { 9 for(i = 1; i <= n; i++)10 scanf("%d",d+i);11 d[0] = d[n+1] = INT_MAX;12 ans = 0;13 while(n >= 2) {14 for(i = 2; i <= n; i++) if(d[i-1] < d[i+1]) break;15 temp = d[i-1] + d[i];16 ans += temp;17 for(j = i-1; j && temp > d[j-1]; j--) d[j] = d[j-1];18 d[j] = temp;19 for(j = i; j <= n; j++) d[j] = d[j+1];20 n--;21 }22 printf("%d\n",ans);23 }24 return 0;25 }View code