频道栏目
首页 > 资讯 > C++ > 正文

POJ3253 Fence Repair (二叉堆)

14-04-27        来源:[db:作者]  
收藏   我要投稿

本文出自:http://blog.csdn.net/svitter

题意:给你几根木板,让你连接起来,每次连接花费为两根长度之和。连接所有的木板,最后最小的花费是多少。

这个题目用贪心即可。即,每次的取两根最小的,花费最少,最后花费就最少。

本题目可以用二叉堆的最关键就在于二叉堆的定义:

大根堆:上面的比下面的大;

小根堆:上面的比下面的小;

通过一维数组最后一个添加或者删除,进行调整。

1.一般堆解法:

时间消耗:

#include 
#include 
#include 
#include 

using namespace std;

__int64 a[20010];
int m, n;

void heap(int m)
{
    int t;
    while(m * 2 <= n)//有子堆
    {
        m = m * 2;
        if(m < n && a[m] > a[m+1]) // 较大的子堆
        {
            m++;
        }
        if(a[m] < a[m / 2]) //
        {
            t = a[m];
            a[m] = a[m/2];
            a[m/2] = t;
        }
        else
            break;
    }
}

void push_heap()
{
    int i = n;
    __int64 x = a[n];
    while(i > 1 && a[i/2] > x)
    {
        a[i] = a[i/2];
        i /= 2;
    }
    a[i] = x;
}

void pop_heap()
{
    __int64 x;
    //swap top.root
    x = a[1];
    a[1] = a[n];
    a[n] = x;

    n--;
    heap(1);
}

void make_heap()
{
    int i;
    for(i = n / 2; i > 0; i --)//从n/2构建即可
    {
        heap(i);
    }
}

void ace()
{
    int i;
    __int64 cur0, cur1, cur, sum;
    while(~scanf("%d", &n))
    {
        for(i = 1; i <= n; i++)
        {
            scanf("%I64d", &a[i]);
        }
        make_heap();
        sum = 0;
        while(n != 1)
        {
            pop_heap();
            cur0 = a[n+1];
            pop_heap();
            cur1 = a[n+1];
            cur = cur0 + cur1;
            sum += cur;
            a[++n] = cur;
            push_heap();
        }
        printf("%I64d\n", sum);
    }
}

int main()
{
    ace();
    return 0;
}


2.类似冒泡解法

时间消耗:


#include 
#include 
#include 
#include 

using namespace std;

__int64 a[20010];
int m, n;


void ace()
{
    int i;
    __int64 cur0, cur1, cur, sum;
    while(~scanf("%d", &n))
    {
        for(i = 1; i <= n; i++)
        {
            scanf("%I64d", &a[i]);
        }
        make_heap();
        sum = 0;
        while(n != 1)
        {
            pop_heap();
            cur0 = a[n+1];
            pop_heap();
            cur1 = a[n+1];
            cur = cur0 + cur1;
            sum += cur;
            a[++n] = cur;
            push_heap();
        }
        printf("%I64d\n", sum);
    }
}

int main()
{
    ace();
    return 0;
}
3.模板STL解法

没有写出来,方法就几个, 没有获取弹出堆首元素的方法。如果你会的话,请告诉我= =

相关TAG标签
上一篇:HDOJ 4612 Warm up
下一篇:HDU4049:Tourism Planning(状态压缩)
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站