巧克力(蓝桥杯)

巧克力

题目描述

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

一天小蓝到超市想买一些巧克力。超市的货架上有很多种巧克力,每种巧克力有自己的价格、数量和剩余的保质期天数,小蓝只吃没过保质期的巧克力,请问小蓝最少花多少钱能买到让自己吃 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;
### 蓝桥杯巧克力问题的Java实现与解题思路 #### 问题描述 儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。小明一共有N块巧克力,其中第i块是Hi × Wi的方格组成的长方形[^2]。 #### 解题思路分析 为了满足每位小朋友都能获得相同大小的一份巧克力,需要找到一种方法使得切割后的巧克力块数量最大化的同时保证每一块都具有相同的面积。考虑到直接枚举可能存在的效率低下问题,在此采用二分查找的方法来优化求解过程[^5]。 对于每一个假设的最大边长`mid`,计算当前条件下能够得到的小正方形总数是否不少于所需分配的数量k。具体做法是从所有巧克力中统计按照该长度裁剪可以获得少合格单位,并据此调整搜索范围直至逼近最优解。 #### Java代码实现 下面给出基于上述逻辑编写的完整版解决方案: ```java import java.util.*; public class ChocolateDistribution { public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); // 总共有的巧克力种类数 long k = sc.nextLong(); // 需要分成几份 List<long[]> cookies = new ArrayList<>(); for(int i=0;i<n;++i){ long h=sc.nextLong(), w=sc.nextLong(); cookies.add(new long[]{h,w}); } System.out.println(maxSquareSize(cookies, k)); } private static long maxSquareSize(List<long[]> cookies, long targetCount) { long low = 1; long high = (long)(Math.pow(1e9, 0.5))+1; while(low<=high){ long mid=(low+high)/2; if(canCutEnoughPieces(mid,cookies,targetCount)){ low=mid+1; }else{ high=mid-1; } } return high; } private static boolean canCutEnoughPieces(long sizeGuess,List<long[]> cookies,long minRequired){ long count=0L; for(var c : cookies){ count+=c[0]/sizeGuess * (c[1]/sizeGuess); } return count>=minRequired; } } ``` 通过这段程序实现了对输入数据的有效处理以及利用二分查找高效寻找最大可行尺寸的功能[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

命运从未公平

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

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

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

打赏作者

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

抵扣说明:

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

余额充值