运输--模拟

传送门

我...手推样例都推不出来

(怀疑样例可真傻

救救孩子

(蒟蒻莫得未来

-------------------------------------------------------------------------------------------

题目描述
现在已知 N 件商品,和搬运它们其中每一件的费用。现在搬家公司老板 Mr.sb 决定让我们每次任意选取 2 件商品。然后这 2 件商品只算一件商品的费用。但是这个商品的搬运费用是将选出的 2 个商品的费用之和除以 k 的运算结果。如此反复。直到只收一件商品的钱。这个就是商店要付的费用。掌柜的想尽可能的少付钱,以便将更多的钱捐给希望工程。所以请你帮他计算一下最少只用付多少钱。


输入
n,k
w1,w2,...,wn(每一件商品的搬运费用)
n,k<=10000

输出
最少付多少钱


样例输入

5 2

1 2 3 4 5

样例输出

1

--------------------------------------------------------------------------------------

贪心:

每次取最大值和次大值合并就好了

(据说特别想合并果子orz

要想合并后的答案放回原序列

再重新去取最大值和次大值排序

反复

直到合并到只剩下了一个值

就是最优费用了

显然每次排序复杂度实在是太不友好le

所以优先队列prioity_queue

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

inline int read()
{
    int sum = 0,p = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
            p = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        (sum *= 10) += ch - '0';
        ch = getchar();
    }
    return p * sum;
}


priority_queue<int>q;
int n,k;
int main()
{
    n = read(),k = read();
    for(int i = 1;i <= n;i++)
    {
        int a = read();
        q.push(a);
    }
    while(q.size() != 1)
    {
        int a = q.top();
        q.pop();
        int b = q.top();
        q.pop();
        int c = (a + b)/k;
        q.push(c);
    }
    printf("%d",q.top());
    return 0;
}
原文地址:https://www.cnblogs.com/darlingroot/p/10890491.html