巧克力
题目描述
小蓝很喜欢吃巧克力,他每天都要吃一块巧克力。
一天小蓝到超市想买一些巧克力。超市的货架上有很多种巧克力,每种巧克力有自己的价格、数量和剩余的保质期天数,小蓝只吃没过保质期的巧克力,请问小蓝最少花多少钱能买到让自己吃 x 天的巧克力。
输入描述
输入的第一行包含两个整数 x, n,分别表示需要吃巧克力的天数和巧克力的种类数。
接下来 n 行描述货架上的巧克力,其中第 i 行包含三个整数 ai, bi, ci,表示第 i 种巧克力的单价为 ai,保质期还剩 bi 天(从现在开始的 bi 天可以吃),数量为 ci。
输出描述
输出一个整数表示小蓝的最小花费。如果不存在让小蓝吃 x 天的购买方案,输出ࠪ -1。
输入输出样例
示例
输入
10 3
1 6 5
2 7 3
3 10 10
输出
18
样例说明
一种最佳的方案是第 1 种买 5 块,第 2 种买 2 块,第 3 种买 3 块。前 5 天吃第 1 种,第 6、7 天吃第 2 种,第 8 至 10 天吃第 3 种。
评测用例规模与约定
对于 30% 的评测用例,n, x ≤ 1000。
对于所有评测用例,1 ≤ n, x ≤ 100000,1 ≤ ai, bi, ci ≤ 109。
解题分析
显然要使花费的钱最少,我们就要尽量选用价格尽量低的巧克力。
对于一个巧克力,设其保质期为b,那么我们仅可能在第1~ b天会吃它。而如果第1~ b天每天都已经安排好了要吃的巧克力,那该巧克力买了就没有任何意义,我们称其为没用的巧克力。
假设我们现在买了一个保质期为b的巧克力,那我们就要尽量将该巧克力放在第b天吃。而如果第b天已经有巧克力吃了,我们就尽量将其放在b-1天吃
如此我们就能保证可以尽可能多的购买价格尽量低的有用的巧克力。
而对于保质期为b的巧克力,要快速确定将其放在哪一天吃, 可以维护-一个记录着没有安排巧克力吃的日期的set,这样我们只要在set中二分第一个小于b的日期就可以快速确定了。然后再通过以上贪心策略,模拟一遍即可。
或者利用队列,从最后一天开始考虑,把符合要求的巧克力都加入备选集合,然后选择价格最便宜的巧克力,用优先队列维护即可。
贪心
下面是对您提供的C++代码的详细注释。
#include<bits/stdc++.h> // 引入所有标准库
using namespace std;
// 定义一个结构体node,用来表示巧克力的属性
struct node
{
int val,days,cnt;