题目描述
现在已知N件商品,和搬运它们其中每一件的费用。现在搬家公司老板Mr.sb决定让我们每次任意选取2件商品。
然后这2件商品只算一件商品的费用。但是这个商品的搬运费用是将选出的2个商品的费用之和除以k的运算结果。
如此反复。直到只收一件商品的钱。这个就是商店要付的费用。掌柜的想尽可能的少付钱,以便将更多的钱捐给希望工程。
所以请你帮他计算一下最少只用付多少钱。
【输入格式】trans.in
【输出格式】
【样例输入】trans.out
【样例输出】
1
输入输出格式
输入格式:
n,k w1,w2.....wn(每一件物品搬运费)
输出格式:
一个数 最少付多少钱
输入输出样例
说明
【数据规模】
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 }
如果你不开心,那我就把右边这个帅傻子分享给你吧,
你看,他这么好看,那么深情的望着你,你还伤心吗?
真的!这照片盯上他五秒钟就想笑了。
一切都会过去的。