POJ3253 Fence Repair【贪心】

我们的小伙伴Bingo真的很调皮,他在上课的路上看到树上有个鸟窝,他就想去把他捅下来,但是鸟窝很高他够不到,于是他就到处找木棍,想把这些木棍接在一起,然后去捅鸟窝。他一共找了N跟木棍 (1 ≤ N ≤ 20,000),每根木棍的长度为 Li (1 ≤ Li ≤ 50,000) 。现在他要把这N根木棍连接在一起,每次连接只能把两根木棍连在一起,而且每连接一次都需要花费一些money去买材料,买这些材料要用的money和要连接的两根木棍的长度之和相等(如:把长度分别为5和8的木棍连在一起,买材料就需要花13元)。Bingo想要花最少的钱来买材料。我们已经知道了他找到的木棍的长度,那么他最少要花多少钱来买材料呢??

Input

第一行为Bingo找到的木棍的数目N(N为整数),之后N行为每根木棍的长度。

Output

Bingo 所需要买材料的最少money

Sample Input






8

Sample Output

48

思路:每次都先挑出最短的两个,然后将他们链接在一起并当做新的一根树枝,继续在他们队列中找最小的两个连接,直到连成一根。跟洛谷那道糖果题一样的思想,我一样的代码就过了。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=20005;
int l[maxn];
int main()
{
    long long ans=0;
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;++i)
        scanf("%d",&l[i]);
    while(n>1)
    {
        int min1=0,min2=1;
        if(l[min1]>l[min2])
            swap(min1,min2);
        for(int i=2;i<n;++i)
        {
            if(l[i]<l[min1])
            {
                min2=min1;
                min1=i;
            }
            else if(l[i]<l[min2])
            {
                min2=i;
            }
        }
        int t=l[min1]+l[min2];
        ans+=t;
        if(min1==n-1)
            swap(min1,min2);
        l[min1]=t;
        l[min2]=l[n-1];
        n--;
    }
    printf("%lld
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/aerer/p/9930974.html