BZOJ3229 石子合并

 

Description

  在一个操场上摆放着一排N堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。
  试设计一个算法,计算出将N堆石子合并成一堆的最小得分。
 

Input

  第一行是一个数N。
  以下N行每行一个数A,表示石子数目。
 

Output

  共一个数,即N堆石子合并成一堆的最小得分。

 

Sample Input

4
1
1
1
1

Sample Output

8

HINT

 

对于 100% 的数据,1≤N≤40000

对于 100% 的数据,1≤A≤200

 
 
正解:GarsiaWachs算法
解题报告:
  神奇的算法,居然可以把石子合并做到O(NlogN),不可思议,感到害怕。
  上午讲题的时候提到了用四边形不等式得出的可以有单调性的N^2的优化DP,然而面对40000的数据还是有一点虚。
  移步学习GarsiaWachs算法:http://www.cnblogs.com/lwq12138/p/5425465.html 或者 http://blog.csdn.net/Regina8023/article/details/45244733
  不详细讲了。
 
 1 //It is made by jump~
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <ctime>
 9 #include <vector>
10 #include <queue>
11 #include <map>
12 #include <set>
13 #ifdef WIN32   
14 #define OT "%I64d"
15 #else
16 #define OT "%lld"
17 #endif
18 using namespace std;
19 typedef long long LL;
20 const int inf = 5201314;
21 const int MAXN = 40011;
22 int a[MAXN];
23 int n;
24 LL ans;
25 
26 inline int getint()
27 {
28        int w=0,q=0;
29        char c=getchar();
30        while((c<'0' || c>'9') && c!='-') c=getchar();
31        if (c=='-')  q=1, c=getchar();
32        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
33        return q ? -w : w;
34 }
35 
36 inline void work(){
37     n=getint();
38     for(int i=1;i<=n;i++) a[i]=getint();
39     int m=n;
40     a[0]=a[n+1]=inf;
41     for(int i=1;i<n;i++) {//最后一次不用做
42     int k;
43     for(int j=1;j<=m;j++) {//从左往右,每次找到第一个满足a[k−1]≤a[k+1]的k,然后合并a[k−1],a[k]
44         if(a[j-1]<a[j+1]) { k=j; break; }
45     }
46     a[k-1]+=a[k];
47     for(int j=k;j<m;j++) a[j]=a[j+1];//左移
48     ans+=a[k-1]; k--;//指向当前处理结点
49     while(k>0 && a[k-1]<=a[k]) { //从当前位置开始向左找第一个a[j]>a[k−1]+a[k]的j,把合并后的值插到j的后面
50         swap(a[k-1],a[k]);
51         k--;
52     }
53     a[m]=inf;
54     m--;
55     }
56     printf(OT,ans);
57 }
58 
59 int main()
60 {
61   work();
62   return 0;
63 }

 

posted @ 2016-07-12 17:36  ljh_2000  阅读(862)  评论(0编辑  收藏  举报