合并果子----(堆的应用)

来源:互联网 发布:彩虹秒赞源码9.8 编辑:程序博客网 时间:2024/04/28 20:41

合并果子人人皆知,然而这并不是DP,是可以每次选最小的就可以对,
but我直接暴力,神奇的TLE了!
于是乎,我用了堆
这里写图片描述

#include<cstdio>#include<cstdlib>#include<iostream>using namespace std;int d[100000];    //堆int main(){    int m,n,i,j,k,l;    cin>>n;    for(i=1;i<=n;i++)    {        cin>>d[i];        k=i;        while(k>1 && d[k]<d[k/2])  //如果d[i]小于左子树,则往上浮        {            swap(d[k],d[k/2]); //上浮过程            k=k/2;        }       }    int len=n,ans=0;    while(len>1)    {        int s=0,u;        s+=d[1]; //取出最小值合并        d[1]=d[len--]; //填充堆顶        u=1;        while(len>=u*2 && d[u]>d[u*2] ||len>=u*2+1 && d[u]>d[u*2+1]) //如果d[u]大于左子树,则像下沉,即调整堆        {            int t=u*2;   //下沉过程            if(d[u*2]>d[u*2+1]) t++;            swap(d[u],d[t]);            u=t;        }        s+=d[1]; //再取一次最小值        d[1]=d[len--];        //d[len+1]=0;        u=1;        while(len>=u*2 && d[u]>d[u*2] ||len>=u*2+1 && d[u]>d[u*2+1])        {            int t=u*2;            if(d[u*2]>d[u*2+1]) t++;            swap(d[u],d[t]);            u=t;        }        ans+=s; //合并果子后又放入堆中,最后剩下的即是解....        d[++len]=s;         u=len;        while(u>1 && d[u]<d[u/2])        {            swap(d[u],d[u/2]);            u=u/2;        }    }    cout<<ans; //解    return 0;}
1 0
原创粉丝点击