Powerful Discount Tickets AtCoder - 4864

Problem Statement
Takahashi is going to buy N items one by one.

The price of the i-th item he buys is Ai yen (the currency of Japan).

He has M discount tickets, and he can use any number of them when buying an item.

If Y tickets are used when buying an item priced X yen, he can get the item for X 2Y (rounded down to the nearest integer) yen.

What is the minimum amount of money required to buy all the items?

Constraints
All values in input are integers.
1≤N,M≤105
1≤Ai≤109
Input
Input is given from Standard Input in the following format:

N M
A1 A2 … AN
Output
Print the minimum amount of money required to buy all the items.

Sample Input 1
3 3
2 13 8
Sample Output 1
9
We can buy all the items for 9 yen, as follows:

Buy the 1-st item for 2 yen without tickets.
Buy the 2-nd item for 3 yen with 2 tickets.
Buy the 3-rd item for 4 yen with 1 ticket.
Sample Input 2
4 4
1 9 3 5
Sample Output 2
6
Sample Input 3
1 100000
1000000000
Sample Output 3
0
We can buy the item priced 1000000000 yen for 0 yen with 100000 tickets.

Sample Input 4
10 1
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000
Sample Output 4
9500000000

题意:
简单的题意,只需要注意时 round down向下取整;
思路;
我想我没做出来的原因是我不会优先队列,更重要的是没想到这个贪心策略;刚开始以后从最大的开始,然后让他用最大的折扣;后来发现这种贪心策略只是局部最优;当前使用的折扣券数量会对以后的折扣价格产生影响;
正确策略:
使每一个优惠券的作用发挥到最大,才是正确的的贪心;用优先队列把所有的商品价格放在里面,然后,每次把价格最高的商品用一张优惠券来处理;再放进队列里面;

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main()
{
	priority_queue<int> q; 
	int n,m;
	cin >>n>>m;
	for(int i=0;i<n;i++)
	{
		int x;
		cin >>x;
		q.push(x);
	}
	while(!q.empty()) 
	{
		int x=q.top();
		q.pop();
		x=x/2;
		q.push(x);
		m--;
		if(m<=0) break;
	}
	ll sum=0;
	while(!q.empty())
	{
		int x=q.top();
		q.pop();
		sum+=x;
	}
	cout <<sum<<endl;
	return 0;
 }
发布了197 篇原创文章 · 获赞 36 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43872728/article/details/103190672