P8769 [蓝桥杯 2021 国 C] 巧克力 题解

本文介绍了一种解决巧克力选择问题的贪心算法,通过堆数据结构维护巧克力,优先选择价格较低且保质期较长的巧克力,确保在有限的库存中获得最大价值。
摘要由CSDN通过智能技术生成

题目传送门

思路

很明显,这是一道贪心题。用堆维护巧克力,把价格低的巧克力放在堆顶,同等价格,保质期低的放在堆顶。

会发现,正着做容易出现一些问题。如果有一个巧克力快到保质期但不是最优的,而最优的巧克力只剩一个,另外的巧克力价格非常高,最优解肯定是要选这个快到保质期的巧克力。但正着做就不会选。

但是,倒着做可以完美的避开这种问题,因为最优的巧克力已经在后面被用了,快到保质期的巧克力就会被选上。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

template<typename T> inline void read(T &x)
{
	x = 0;
	T f = 1;char ch = getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')
		{
			f = -1,ch = getchar();
			break;
		}
		ch = getchar();
	}
	while(ch>='0'&&ch<='9')
		x = (x<<3)+(x<<1)+ch-48,ch = getchar();
	x*=f;
}
template<typename T> inline T read()
{
	T x;read(x);return x;
}
template<typename T> inline void write(T x)
{
    if(x<0) x = -x,putchar('-');
    if(x<=9) return putchar(x+48),void();
    write(x/10);
    putchar(x%10+48);
}
template<typename T> inline void writen(T x)
{
    write(x);
    puts("");
}
const int N = 1e5+5; 
struct node{
	mutable int a,b,c;//价格,保质期,数量
	void init() {read(a),read(b),read(c);}
	friend bool operator < (node x,node y)
	{
		return (x.a==y.a)?(x.b>y.b):(x.a>y.a);//由于是大根堆,小于就要反着定义
	}
}a[N];
int n,k,ans;
priority_queue<node> q;
bool cmp(node x,node y) {return x.b>y.b;}
signed main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	read(k),read(n);
	for(int i = 1;i<=n;i++)
		a[i].init();
	sort(a+1,a+n+1,cmp);//按照保质期从大到小排序
	int now = 1;
	for(int i = k;i;--i)
	{
		while(a[now].b>=i)//加入保质期合法的巧克力 
			q.push(a[now]),++now;
		if(q.empty()) return puts("-1"),0;//没有可以选的巧克力
		ans+=q.top().a;--q.top().c;
		if(!q.top().c) q.pop();//不能继续用 
	}
	write(ans);
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值