POJ 3253

题意:分割木板每次切断时,需要的代价是这块木板的长度。求最小代价(哈夫曼树)

题解:每次找出最短的木板L1和次短的木板L2,意味着他们是从一块长度为( L1+L2 )木板上切割下来的,然后把( L1+L2 )这块板放进数列把L1和L2从数列中删掉,数列长度减一,依次循环。

注意:当最小的板为当前数列的最后一块,就应该把( L1+L2 )放在L2的位置,因为每做一次数列长度就要减一。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cctype>
 5 #include <cmath>
 6 #include <time.h>
 7 #include <string>
 8 #include <map>
 9 #include <stack>
10 #include <set>
11 #include <queue>
12 #include <vector>
13 #include <algorithm>
14 #include <iostream>
15 using namespace std;
16 typedef long long ll;
17 typedef pair<int,int> P;
18 #define PI acos( -1.0 )
19 const double E = 1e-8;
20 
21 const int NO = 20000 + 5;
22 int a[NO];
23 int n;
24 ll ans = 0;
25 
26 void Solve()
27 {
28     while( n > 1 )
29     {
30         int x = 0, y = 1;
31         if( a[x] > a[y] ) swap( x, y );
32         for( int i = 2; i < n; ++i )
33         {
34             if( a[x] > a[i] ) {
35                 y = x;
36                 x = i;
37             }
38             else if( a[y] > a[i] )
39                 y = i;
40         }
41         int t = a[x] + a[y];
42         ans += t;
43         if( x == n-1 ) swap( x, y );
44         a[x] = t;
45         a[y] = a[n-1];
46         --n;
47     }
48     printf( "%lld", ans );
49 }
50 
51 int main()
52 {
53     scanf( "%d", &n );
54     for( int i = 0; i < n; ++i )
55         scanf( "%d", &a[i] );
56     Solve();
57     return 0;
58 }
View Code
原文地址:https://www.cnblogs.com/ADAN1024225605/p/4088202.html