[SDOI2008]石子合并 题解
GarsiaWachs算法专门解决石子合并问题:
设一个序列是A[0..n-1],每次寻找最小的一个满足A[k-1]<=A[k+1]的k,那么我们就把A[k]与A[k-1]合并,并向前寻找一个第一个超过他们的和的数,把这个数插入到他后面;
#include<bits/stdc++.h> #define inc(i,a,b) for(register int i=a;i<=b;i++) #define dec(i,a,b) for(register int i=a;i>=b;i--) using namespace std; long long ans,n; vector<int> l; int merge() { register int k=l.size()-2; inc(i,0,l.size()-2){ if(l[i]<=l[i+2]){ k=i; break; } } register int tmp=l[k]+l[k+1]; l.erase(l.begin()+k); l.erase(l.begin()+k); register int in=-1; dec(i,k-1,0){ if(l[i]>tmp){ in=i; break; } } l.insert(l.begin()+in+1,tmp); return tmp; } int main() { scanf("%d",&n); inc(i,1,n){ register int tmp; scanf("%d",&tmp); l.push_back(tmp); } inc(i,0,n-2) ans+=merge(); cout<<ans; return 0; }
众人皆醉我独醒,举世皆浊我独清