POJ 1738 石子合并2 GarsiaWachs算法
石子合并(GarsiaWachs算法)
只能用该算法过!!!
详解看代码
1 //#pragma comment(linker, "/STACK:167772160")//手动扩栈~~~~hdu 用c++交 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<iostream> 6 #include<queue> 7 #include<stack> 8 #include<cmath> 9 #include<set> 10 #include<algorithm> 11 #include<vector> 12 // #include<malloc.h> 13 using namespace std; 14 #define clc(a,b) memset(a,b,sizeof(a)) 15 #define LL long long 16 const int Inf = 0x3f3f3f3f; 17 const double eps = 1e-5; 18 const double pi = acos(-1); 19 // inline int r(){ 20 // int x=0,f=1;char ch=getchar(); 21 // while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();} 22 // while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 23 // return x*f; 24 // } 25 26 int stone[50010]; 27 int n,t,ans; 28 29 void combine(int k){ 30 int tem=stone[k]+stone[k-1];//合并k和k-1堆 31 ans+=tem; 32 for(int i=k;i<t-1;i++) stone[i]=stone[i+1];//k以后的往前移位 33 t--; 34 int j; 35 for(j=k-1;j>0&&stone[j-1]<tem;j--) stone[j]=stone[j-1];//k-1以后的往后移位 36 stone[j]=tem;//在j处插入tem 37 while(j>2&&stone[j-2]<=stone[j]){//在新得到的序列里递归处理 38 int d=t-j; 39 combine(j-1); 40 j=t-d;//回溯 41 } 42 } 43 int main(){ 44 while(~scanf("%d",&n)){ 45 if(n==0) break; 46 for(int i=0;i<n;i++) scanf("%d",&stone[i]); 47 t=1; 48 ans=0; 49 for(int i=1;i<n;i++){ 50 stone[t++]=stone[i]; 51 while(t>3&&stone[t-3]<stone[t-1]) combine(t-2);//从1开始遍历到结尾 52 } 53 while(t>1) combine(t-1);//合并完后如果不为一堆再合并一次 54 printf("%d\n",ans); 55 } 56 return 0; 57 }