蓝桥杯国赛每日一题:巧克力(贪心,堆)

题目描述:

小蓝很喜欢吃巧克力,他每天都要吃一块巧克力。

一天小蓝到超市想买一些巧克力。超市的货架上有很多种巧克力,每种巧克力有自己的价格、数量和剩余的保质期天数,小蓝只吃没过保质期的巧克力,请问小蓝最少花多少钱能买到让自己吃 x 天的巧克力。

输入格式

输入的第一行包含两个整数 x,n,分别表示需要吃巧克力的天数和巧克力的种类数。

接下来 n 行描述货架上的巧克力,其中第 i 行包含三个整数 ai​,bi​,ci​,表示第 i 种巧克力的单价为 ai​,保质期还剩 bi​ 天(从现在开始的 bi​ 天可以吃),数量为 ci​。

输出格式

输出一个整数表示小蓝的最小花费。如果不存在让小蓝吃 x 天的购买方案,输出 −1。

输入输出样例

输入 #1复制

10 3
1 6 5
2 7 3
3 10 10

输出 #1复制

18

说明/提示

【样例说明】

一种最佳的方案是第 1 种买 5 块,第 2 种买 2 块,第 3 种买 3 块。前 5 天吃第 1 种,第 6、7 天吃第 2 种,第 8至 10 天吃第 3 种。

【评测用例规模与约定】

对于 30% 的评测用例 n,x≤1000。

对于所有评测用例,1≤n,x≤10^5,1≤ai​,bi​,ci​≤10^9。

 解题思路:

由于有些巧克力日期过期后不能再食用,所以将时间倒着枚举,查看巧克力的日期时候>=当前日期,则可使用。

按日期从小到大排序后,再按单价存入一个小根堆中来维护,每次取出日期符合,且价格便宜的巧克力,加上当前节点的价钱。

参考代码:

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 1e5+10;
struct Chocolate
{
	int a,b,c;
	friend bool operator < (Chocolate x,Chocolate y)
	{
		return x.a > y.a;
	}
}w[N];

bool cmp(Chocolate x,Chocolate y) {
	return x.b > y.b;
}
priority_queue<Chocolate>q;

int t,n;

int main()
{
  cin>>t>>n;
	for(int i=1;i<=n;i++) cin>>w[i].a>>w[i].b>>w[i].c;
	
	sort(w+1,w+1+n,cmp);
	

	int j = 1;
	LL res = 0;
	for(int i=t;i>=1;i--)
	{
		while(j<=n && w[j].b>=i) q.push(w[j++]);
		if(q.empty())
		{
			cout<<"-1"<<endl;
			return 0;
		}
		Chocolate m = q.top();
		q.pop();
		res += m.a;
		m.c--;
		if(m.c) q.push(m);
	}
	cout<<res<<endl;
	return 0;
} 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cocobol0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值