[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;
}

 

posted @ 2019-10-29 15:44  神之右大臣  阅读(185)  评论(0编辑  收藏  举报