版权声明:转载无所谓的。。。 https://blog.csdn.net/xuxiayang/article/details/82713685
大意
给定 件商品,现在你有 张降价券,可以让 降至 在购买金额不超过 最多能购买的物品数量
思路
首先显然可以发现,用降价券是永远比不用要好的,所以我们在一开始优先选择让降价后代价更低的,然后再依次补上,这种算法是存在漏洞的,所以只能拿80分
若要拿一百分,通过观察发现,有的时候一些本价本来就很低的商品用降价券是有点浪费的,我们完全可以话费 的代价换一张降价券给另一件没有被降价的商品,而显然另一件商品的代价必须要小于之前我们说的代价才能交换
这就是一种新的思想,可撤销贪心!
代码
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;int n,k,p[150001],q[150001],nused;long long m;
bool used[150001];
struct node{long long num;int id;};
priority_queue<node>qp,qq;
priority_queue<long long,vector<long long>,greater<long long> >cz;
inline bool operator <(node x,node y){return x.num>y.num;}//按照价值从小到大排
signed main()
{
cin>>n>>k>>m;
for(register int i=1;i<=n;i++) scanf("%d%d",p+i,q+i),qp.push((node){p[i],i}),qq.push((node){q[i],i});//qp为降价前的,qq为降价后的
for(register int i=1;i<=k;i++) cz.push(0ll);//cz为差值,我们一开始假设所有的差值为0,这样也就是假设所有能用降价券的商品都用了降价券
while(m>0&&nused<n)
{
while(used[qq.top().id]) qq.pop();
while(used[qp.top().id]) qp.pop();//如果这些商品已经买走了则弹出
if(cz.top()+qq.top().num<qp.top().num)//若差价是要下于另一件商品的原价的,把优惠券给另一件商品
{
node x=qq.top();
long long cost=cz.top()+x.num;//计算代价
if(m<cost) break;//买不起就退出吧
m-=cost;//买了
cz.pop();
cz.push(p[x.id]-q[x.id]);//新增差值
used[x.id]=true;//标记已经买了
}
else//否则不换
{
node x=qp.top();
long long cost=x.num;//直接把这个商品买走
if(m<cost) break;//买不起别买了
m-=cost;//买走
used[x.id]=true;//标记已经被买走了
}
nused++;//多买了一件
}
printf("%d",nused);//输出
}