P2094 运输

题目描述

现在已知N件商品,和搬运它们其中每一件的费用。现在搬家公司老板Mr.sb决定让我们每次任意选取2件商品。

然后这2件商品只算一件商品的费用。但是这个商品的搬运费用是将选出的2个商品的费用之和除以k的运算结果。

如此反复。直到只收一件商品的钱。这个就是商店要付的费用。掌柜的想尽可能的少付钱,以便将更多的钱捐给希望工程。

所以请你帮他计算一下最少只用付多少钱。

【输入格式】trans.in

【输出格式】

【样例输入】trans.out

【样例输出】

1

输入输出格式

输入格式:

 

n,k w1,w2.....wn(每一件物品搬运费)

 

输出格式:

 

一个数 最少付多少钱

 

输入输出样例

输入样例#1: 复制
5 2
1 2 3 4 5
输出样例#1: 复制
1

说明

【数据规模】

n、k、wi均为非负数

n和k<=10000

 

应该首先能想到一种贪心思路,

从大到小排序,

然后把大的相加,除二,然后继续,

 

刚开始就这么写的,交上去40分,

 

然后突然顿悟!

相加除二之后数就变了!

而且这个数也还要参与运算,

所以要不断排序!!!

对了!

思路就是这样!

但是,

不断排序,,

好熟悉啊!

这不就用到我前几天刚学的堆了吗!!!

哇塞!

amazing!

 

那就是堆了,

好像也可以看做板子了。。

 

大根堆,

弹出,弹出,记录两个最大的,加和除二,

再把结果放入堆,没错!

就是这样!

 

看代码吧:

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<queue> 
 7 using namespace std;
 8 
 9 int n,k,x;
10 priority_queue<int,vector<int> > q;//大根堆吧 
11 
12 int main()
13 {
14     scanf("%d%d",&n,&k);
15     for(int i=1;i<=n;++i)
16     {
17         scanf("%d",&x);
18         q.push(x);
19     }    
20     while(q.size()>1)
21     {
22         int a=q.top();
23         q.pop();
24         int b=q.top();
25         q.pop();
26         q.push((a+b)/k);
27     }    
28     printf("%d",q.top());
29     return 0;
30 }

 


如果你不开心,那我就把右边这个帅傻子分享给你吧, 

你看,他这么好看,那么深情的望着你,你还伤心吗? 

真的!这照片盯上他五秒钟就想笑了。 

一切都会过去的。

posted @ 2018-08-07 20:04  孟东行#  阅读(288)  评论(0编辑  收藏  举报