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

P5569 【SDOI2008】 石子合并(黑科技)

时间:2019-10-23 09:32:56      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:时间复杂度   时间   break   def   需要   har   efi   插入   贪心算法   

\(Solution\)

\(n\)\(100\)左右时,直接\(O(n^3)\)区间\(DP\)
\(n\)\(40000\)左右时,需要用贪心算法:加西亚-瓦克斯算法(\(Garsia\ Wachs\))
注:这个方法仅求石子合并的最小答案
这是大概的流程
技术图片
这是关于\(Garsia\ Wachs\)算法的正确性证明:传送门
时间复杂度最坏为\(O(n^2)\),但是基本跑不满,数据随机的话\(n=40000\)能搞过去
代码使用链表实现,方便删除和插入操作,边界什么的比较麻烦,一定要注意,可以看看代码注释

\(Code\)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define re register
#define maxn 1000010
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
ll ans,tmp;
int l[maxn],r[maxn],v[maxn],n,a[maxn],cnt,num;
int main()
{
    n=read();
    for(re int i=1;i<=n;++i) 
    {
        a[i]=read();
        v[i]=a[i],l[i]=i-1,r[i]=i+1;
    }
    v[0]=v[n+1]=INF;//赋为无穷大作为边界,保证所有删除插入都在边界内完成 
    r[0]=1,l[0]=-1;//这里要赋成-1,否则到了0,l[0]=0会一直死循环 
    l[n+1]=n,r[n+1]=0;
    cnt=n;
    num=n+1;//从n+2开始编号 
    while(cnt>1)//=1的时候跳出就行了 
    {
        cnt--;
        int now=0;
        while(r[r[now]]!=0)//不要写>=n+1,因为新的编号是>=n+1的,往右找是0就到了真是的边界,退出 
        {
            if(v[r[r[now]]]>=v[now]) break;
            now=r[now];
        }
        tmp=v[now]+v[r[now]];
        ans+=tmp;统计答案
        r[l[now]]=r[r[now]];
        l[r[r[now]]]=l[now];//删除操作,删除两个 
        now=l[now];
        while(now>=0)//这里可以写>=0,往左是-1就代表到边界了 
        {
            if(v[now]>tmp) break;
            now=l[now];
        }
        num++;
        l[num]=now,r[num]=r[now],v[num]=tmp;
        r[now]=num;//插入操作 
        l[r[num]]=num;
    }
    printf("%d\n",ans);
    return 0;
}           

P5569 【SDOI2008】 石子合并(黑科技)

标签:时间复杂度   时间   break   def   需要   har   efi   插入   贪心算法   

原文地址:https://www.cnblogs.com/Liuz8848/p/11723914.html

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