首页 > 其他分享 >周赛363 Leetcode 2861. 最大合金数

周赛363 Leetcode 2861. 最大合金数

时间:2023-10-16 11:46:51浏览次数:49  
标签:2861 周赛 int 合金 budget num left Leetcode stock

题解

k个小问题,对每台机器分别计算这台机器最多能制造出多少合金,然后所有机器取max,就是最大合金数。
参数太多不好直接算
如果暴力,枚举制造1份合金,2份合金,... ,但是budget和stock都是1e8,会超时
但是暴力可以给我们一个启发:制造的合金数越多,花的钱越多。我们是否可以猜一个答案?如果制造num份合金,花的钱<=budget,那么不用枚举小于num的合金数了,因为能制造num份合金,一定能制造num-1份合金。如果制造num份合金,花的钱>budget,那么就不用枚举大于num的合金数了。满足单调性。可以二分。最少制造0份合金,最多制造1e9(可以这样直接写)份。假设composition和cost取最小都是1,如果stock是(2,3,4),那么在不买其他合金的情况下最多只能造两块合金。所以最多可以制造min(stock) + budget // k份合金,这是二分的上界(粗略)。
二分的范围就是把不知道的东西框在这个区间里面,这里写的是开区间二分。在满足check时,意味着猜的num比较小,就把二分的左端点变大。二分返回什么?二分返回就取决于check成立时赋给什么。check成立时middle = left。答案就是left。最后对于所有机器的left取max就是答案。
要注意的点:check函数中num要开longlong,否则在计算money += (com[i] * num - stock[i]) * cost[i];会溢出。check函数传参数vector时用&,这样快很多。

class Solution {
public:
    bool check(long long num, int n, int budget, vector<int>& stock, vector<int>& com, vector<int>& cost)
    {
        long long money = 0;
        for(int i = 0; i < n; i++)
        {
            if(stock[i] < com[i] * num)
                money += (com[i] * num - stock[i]) * cost[i];
            if(money > budget) return false;
        }
        return true;
    }
    int maxNumberOfAlloys(int n, int k, int budget, vector<vector<int>>& composition, vector<int>& stock, vector<int>& cost) {
        int ans = 0;
        int maxx = *min_element(stock.begin(), stock.end()) + budget;
        for(auto &com: composition)
        {
            int left = 0, right = maxx + 1;
            while(left + 1 < right)
            {
                int mid = (left + right) / 2;
                (check(mid, n, budget, stock, com, cost) ? left : right) = mid;
            }
            ans = max(ans, left);
        }
        return ans;
    }
};

标签:2861,周赛,int,合金,budget,num,left,Leetcode,stock
From: https://www.cnblogs.com/Maxx-el/p/17766649.html

相关文章

  • LeetCode54. 螺旋矩阵Ⅰ
    题目描述给你一个m行n列的矩阵matrix,请按照顺时针螺旋顺序,返回矩阵中的所有元素。示例提交的代码classSolution{publicList<Integer>spiralOrder(int[][]matrix){//行数intm=matrix.length;//列数intn=matrix[0].......
  • #yyds干货盘点# LeetCode程序员面试金典:H 指数
    题目:给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。根据维基百科上 h指数的定义:h 代表“高引用次数”,一名科研人员的 h 指数 是指他(她)至少发表了 h 篇论文,并且每篇论文 至少 被引用 h 次......
  • #yyds干货盘点# LeetCode程序员面试金典:四数相加 II
    1.简述:给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i,j,k,l) 能满足:0<=i,j,k,l<nnums1[i]+nums2[j]+nums3[k]+nums4[l]==0 示例1:输入:nums1=[1,2],nums2=[-2,-1],nums3=[-1,2],nums4=[0,2]输出:2......
  • LeetCode59. 螺旋矩阵Ⅱ
    题目描述给你一个正整数n,生成一个包含1到n2所有元素,且元素按顺时针顺序螺旋排列的nxn正方形矩阵matrix。示例提交的代码classSolution{intmatrixLen=0;publicint[][]generateMatrix(intn){ //初始化空数组int[][]matrix=newint[n][......
  • leetcode2845. 统计趣味子数组的数目
    题解classSolution{public:longlongcountInterestingSubarrays(vector<int>&nums,intmodulo,intk){inta[100010];unordered_map<int,int>mp;mp[0]=1;longlongans=0;intpre=0;......
  • LeetCode Day04 24&19&02.07&142
    24. 两两交换链表中的节点这题使用虚拟头结点会更好做,因为有虚拟头结点我们交换结点的时候步骤会更加清晰。操作此类有指针类型的题目要注意:1.画图避免混乱2.注意指针先后顺序classSolution{publicListNodeswapPairs(ListNodehead){ListNodedumyhea......
  • LeetCode209. 长度最小的子数组
    题目描述给定一个含有n个正整数的数组和一个正整数target。找出该数组中满足其总和大于等于target的长度最小的连续子数组[numsl,numsl+1,...,numsr-1,numsr],并返回其长度。如果不存在符合条件的子数组,返回0。示例输入:target=7,nums=[2,3,1,2,4,3]输出:2......
  • Acwing.第125场周赛
    比赛链接数量给定一个正整数n,请你计算[1,n]范围内一共有多少个正整数满足能被2整除,但不能被3整除。输入格式一个正整数n。输出格式一个整数,表示满足条件的整数的数量。数据范围前3个测试点满足1≤n≤100。所有测试点满足1≤n≤10000。思路:一个比较简单的模拟......
  • [LeetCode] 1354. Construct Target Array With Multiple Sums 多次求和构造目标数组
    Youaregivenanarray target ofnintegers.Fromastartingarray arr consistingof n 1's,youmayperformthefollowingprocedure:let x bethesumofallelementscurrentlyinyourarray.chooseindex i,suchthat 0<=i<n andsettheva......
  • #yyds干货盘点# LeetCode程序员面试金典:整数转换英文表示
    题目:将非负整数 num 转换为其对应的英文表示。 示例1:输入:num=123输出:"OneHundredTwentyThree"示例2:输入:num=12345输出:"TwelveThousandThreeHundredFortyFive"示例3:输入:num=1234567输出:"OneMillionTwoHundredThirtyFourThousandFiveHundredSixtySe......