标签:
题目大意:石子合并数据超大版。
思路:引入一种GarsiaWachs算法。每次找到i最小的一个ai[i-1]<ai[i+1]的位置,把ai[i]和ai[i-1]合并,然后作为一个石子放入i之前离它最近的比它大的那个石子后面。(具体的证明并不是很清楚,希望有大神能指点一下。)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxnode 40005 #define LL long long using namespace std; int ai[maxnode]={0},t; LL ans=0; void work(int x) { int tmp=ai[x]+ai[x-1];ans+=(LL)tmp;int i,j; for (i=x;i<t-1;++i) ai[i]=ai[i+1]; --t; for (i=x-1;i&&ai[i-1]<tmp;--i) ai[i]=ai[i-1]; ai[i]=tmp; while(i>=2&&ai[i-2]<=ai[i]){ j=t-i;work(i-1);i=t-j; } } int main() { int i,j,n;scanf("%d",&n); for (i=0;i<n;++i) scanf("%d",&ai[i]); t=1; for (i=1;i<n;++i){ ai[t++]=ai[i]; while(t>=3&&ai[t-3]<=ai[t-1]) work(t-2); } while(t>1) work(t-1); printf("%I64d\n",ans); }
标签:
原文地址:http://www.cnblogs.com/Rivendell/p/4795503.html