poj 3253

合并果子倒过来,贪心策略的正确性嘛。。大约凭借直觉想一下,因为次数要不停的往后累加,所以越小的越早合并越好,这样对后面影响小。严格证明就是huffman tree了。话说类似的贪心策略好像还有srm536的1000pt,因为那个题要求最大的合并方法,所以越小的越靠前合并对后面的影响就越小。

这种题,先用stl爽一下!

# include <cstdio>
# include <algorithm>
# include <string>
# include <cstring>
# include <iostream>
# include <queue>
typedef long long ll;
using namespace std;
priority_queue<int,vector<int>,greater<int> > q;
int main()
{
    int n,t,i;
    ll ans = 0ll;
    scanf("%d",&n);
    for (i=0;i<n;++i)
    {
        scanf("%d",&t);
        q.push(t);
    }
    while (q.size()!=1)
    {
        int a = q.top();
        q.pop();
        int b = q.top();
        q.pop();
        ans += (a+b);
        q.push(a+b);
    }    
    printf("%lld
",ans);
    return 0;
}
View Code

 当然像我这种弱b还要手写个堆锻炼一下代码能力啊。。

看下面 - -

# include <cstdio>
# include <algorithm>
# include <string>
# include <cstring>
# include <iostream>
# include <queue>
typedef long long ll;
using namespace std;

int heap[50000],len=0;
void push(int k)
{
    heap[++len] = k;
    int i = len;
    while (i!=1&&heap[i]<heap[i/2])
    {
        swap(heap[i],heap[i/2]);
        i /= 2;
    }    
}
int top()
{
    return heap[1];
}
void pop()
{
    if (len == 1) len--;
    else
    {
        int i = 1,j;
        heap[1] = heap[len];
        len--;
        while (i<=len)
        {
            if (i*2<=len&&(i*2+1)<=len)
            {
                if (heap[i*2]<heap[i*2+1])
                     j = i*2;
                else
                    j = i*2+1;
                if (heap[i]>heap[j])
                {
                    swap(heap[i],heap[j]);
                    i = j;    
                    continue;
                }
            }
            else if (i*2<=len&&heap[i]>heap[i*2])
            {
                swap(heap[i],heap[i*2]);
                i *= 2;
                continue;
            }    
            break;
        }
    }
}

int main()
{
    int n,t,i;
    ll ans = 0ll;
    scanf("%d",&n);
    for (i=0;i<n;++i)
    {
        scanf("%d",&t);
        push(t);
    }
    while (len!=1)
    {
        int a = top();
        pop();
        int b = top();
        pop();
        ans += (a+b);
        push(a+b);
    }
    printf("%lld
",ans);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/1carus/p/3395169.html