码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj3229 石子合并

时间:2015-09-09 19:19:30      阅读:593      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:石子合并数据超大版。

思路:引入一种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);
}
View Code

 

bzoj3229 石子合并

标签:

原文地址:http://www.cnblogs.com/Rivendell/p/4795503.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!