POJ 3253 Fence Repair

贪心法

#include <iostream>
#include <algorithm>

using namespace std;

//洛谷P1090 合并果子
int L[10001] = {0};

int main()
{
    /*第一行是一个整数 n(1≤n≤10000) ,表示果子的种类数。
    **第二行包含 n 个整数,用空格分隔,第 i 个整数(1≤ai≤20000) 是第 i 种果子的数目。*/

    int N;
    cin >> N;
    for(int i = 0;i < N;i++)
    {
        cin >> L[i];
    }

    long long ans = 0; //200000000

    while(N > 1)
    {
        int mii1 = 0, mii2 = 1;
        if(L[mii1] > L[mii2])
            swap(mii1, mii2);   //头文件algorithm
            //这里的swap是为了确保mii1指向的是最小的

        for(int i = 2;i < N;i++)//因为mii1已经指向0 1中最小的,所以i直接从2开始即可
        {
            if(L[i] < L[mii1])//发现更小的
            {
                mii2 = mii1;//目前的mii1转移给mii2 以保证mii2指向的是次小的
                mii1 = i;//mii1指向最小的
            }

            else if(L[i] < L[mii2])//虽然比mii大但是比mii2小
            {
                mii2 = i;//与mii2下标互换以确保mii2指向次小
            }
        }

        //将两块板拼合
        int t = L[mii1] + L[mii2]; //合并果子需要的花费 从小向大排列 总花费便会最小
        ans += t;//将本次合并花费加入到总花费中去

        if(mii1 == N - 1) //如果mii1指向的是最后一块
            swap(mii1, mii2);//此时mii2指向最后一块 mii1指向次小的板
        L[mii1] = t;//最小板被加和取代
        L[mii2] = L[N - 1];//次小板被最后一块取代
        N--;//扔掉最后一个 指针前移(但其实扔掉的是目前的最小和次小 通过前面的互换保留了最后一块 并且把新的和放入排序)
    }

    cout << ans;

    return 0;
}


优先队列

#include <iostream>
#include <queue>
using namespace std;

//N [1,20000]
int main()
{
    int N, x, a = 0, b = 0;
    long long sum = 0;
    priority_queue<int, vector<int>, greater<int> >que;
    cin >> N;
    while(N)
    {
        N--;
        cin >> x;
        que.push(x);
    }//元素逐个入队

    while(que.size() != 1)
    {
        //cout << "size = " << que.size() << endl;
        a = que.top();
        //cout << "a = " << a << endl;
        que.pop();
        b = que.top();
        //cout << "b = " << b << endl;
        que.pop();
        sum += a;
        sum += b;
        //cout << "sum = " << sum << endl;
        que.push(a+b);
        //cout << "after size = " << que.size() << endl;
    }

    cout << sum << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值