1. 程式人生 > >POJ3253 Fence Repair【貪心】

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

5  3  4  6  1  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\n",ans);
    return 0;
}