Merge nyoj 737 stones (1)

Source: Internet
Author: User
Merge stones (1)Time Limit: 1000 MS | memory limit: 65535 kb difficulty: 3
Description
There are n piles of stones in a row, each pile of stones has a certain number. Now we want to build n piles of stones into a pile. The merge process can only pile the adjacent two piles of stones into a pile each time, the cost of each merge is the sum of the two piles of stones, after the N-1 merge into a pile. Obtain the minimum total cost.
 
Input
There are multiple groups of test data, input to the end of the file.
The first line of each group of test data has an integer N, indicating that there are n piles of stones.
The next row contains N (0 <n <200) numbers, which respectively indicate the number of N stones separated by spaces.
Output
The minimum value of the total output cost, which occupies a single row.
Sample Input
31 2 3713 7 8 16 21 4 18
Sample output
9239
Source
Classic Problems
Uploaded
TC _ Hu rendong

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
 
  

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.