【题型总结】二分答案之最大化最小化

简介: 【题型总结】二分答案之最大化最小化

最大化最小值

分享巧克力【LC1231】

You have one chocolate bar that consists of some chunks. Each chunk has its own sweetness given by the array sweetness.


You want to share the chocolate with your k friends so you start cutting the chocolate bar into k + 1 pieces using k cuts, each piece consists of some consecutive chunks.


Being generous, you will eat the piece with the minimum total sweetness and give the other pieces to your friends.


Find the maximum total sweetness of the piece you can get by cutting the chocolate bar optimally.


你有一大块巧克力,它由一些甜度不完全相同的小块组成。我们用数组 sweetness 来表示每一小块的甜度。


你打算和 K 名朋友一起分享这块巧克力,所以你需要将切割 K 次才能得到 K+1 块,每一块都由一些 连续 的小块组成。


为了表现出你的慷慨,你将会吃掉 总甜度最小 的一块,并将其余几块分给你的朋友们。


请找出一个最佳的切割策略,使得你所分得的巧克力 总甜度最大,并返回这个 最大总甜度。

思路:

  • 题意:将数组sweetness分割成连续的k+1个子数组,返回分割后的子数组中和最小的最大值。
  • 本题的单调性为:当**最小甜度【连续子数组和的最小值】**最大,最多分割的份数越小,那么可以通过二分查找法找到最终答案

image.png

class Solution {
    public int maximizeSweetness(int[] sweetness, int k) {
        int n = sweetness.length;
        int[] preSum = new int [n + 1];
        for (int i = 0; i < n; i++){
            preSum[i + 1] = preSum[i] + sweetness[i];
        }
        int l = 1, r = preSum[n] / (k + 1);
        int ans = 0;
        while (l <= r){
            int mid = (l + r) / 2;
            if (check(mid, preSum, k + 1)){
                ans = mid;
                l = mid + 1;
            }else{
                r = mid - 1;
            }
        }
        return ans;
    }
    public boolean check(int min, int[] preSum, int k){
        int count = 0;
        int preIndex = 0;
        for (int i = 1; i < preSum.length; i++){
            if (preSum[i] - preSum[preIndex] >= min){
                count++;
                preIndex = i;
            }
        }
        return count >= k;
    }
}

image.png

class Solution {
    public int maximizeSweetness(int[] sweetness, int k) {
        int n = sweetness.length;
        int sum = 0;
        for (int i = 0; i < n; i++){
            sum += sweetness[i];
        }
        int l = 1, r = sum / (k + 1);
        int ans = 0;
        while (l <= r){
            int mid = (l + r) / 2;
            if (check(mid, sweetness, k + 1)){
                ans = mid;
                l = mid + 1;
            }else{
                r = mid - 1;
            }
        }
        return ans;
    }
    public boolean check(int min, int[] sweetness, int k){
        int count = 0;
        int sum = 0;
        for (int i = 0; i < sweetness.length; i++){
            sum += sweetness[i];
            if (sum >= min){
                count++;
                sum = 0;
            }
        }
        return count >= k;
    }
}

image.png

两球间的磁力【LC1552】

在代号为 C-137 的地球上,Rick 发现如果他将两个球放在他新发明的篮子里,它们之间会形成特殊形式的磁力。Rick 有 n 个空的篮子,第 i 个篮子的位置在 position[i]

Morty 想把 m 个球放到这些篮子里,使得任意两球间 最小磁力 最大。

已知两个球如果分别位于 xy ,那么它们之间的磁力为 |x - y|

给你一个整数数组 position 和一个整数 m ,请你返回最大化的最小磁力。


思路:

  • 首先,二分查找的核心就是找到具有单调性的正确查找对象(来自北枝大佬)
  • 一般来说,查找对象就是题目要求的值,这里为最小磁力【最小球间距】
  • 本题的单调性为,最小磁力越大,最多能放置的球的个数越小

image.png

class Solution {
    public int maxDistance(int[] position, int m) {
        Arrays.sort(position);
        int n = position.length;
        int l = 1, r = position[n - 1] - position[0];
        int ans = 0;
        while (l <= r){
            int mid = (l + r) / 2;
            if (check(mid, position, m)){
                ans = mid;
                l = mid + 1;
            }else{
                r = mid - 1;
            }
        }
        return ans;
    }
    public boolean check (int y, int[] position, int m){
        int count = 1;
        int pre = position[0];
        for (int i = 1; i < position.length; i++){
            if (position[i] - pre >= y){
                count++;
                pre = position[i];
            }
        }
        return count >= m;
    }
}

image.png

礼盒的最大甜蜜度【LC2517】

You are given an array of positive integers price where price[i] denotes the price of the ith candy and a positive integer k.


The store sells baskets of k distinct candies. The tastiness of a candy basket is the smallest absolute difference of the prices of any two candies in the basket.


Return the maximum tastiness of a candy basket.

思路:使用二分查找的方式寻找最大甜蜜度

  • 本题的单调性为:当**最小甜蜜度【数组中任意两个元素的差值的绝对值的最小值】**越大,糖果的可以选择的种类越小【选取的数组中的元素个数】,因此可以通过二分查找法找到最终答案

image.png

class Solution {
    public int maximumTastiness(int[] price, int k) {
        Arrays.sort(price);
        int n = price.length;
        int l = 0, r = price[n - 1] - price[0];
        int ans = 0;
        while (l <= r){
            int mid = (r + l) / 2;
            if (check(price, mid ,k)){
                ans = mid;
                l = mid + 1;
            }else{
                r = mid - 1;
            }
        }
        return ans;
    }
    public boolean check(int[] price, int m, int k){
        int count = 1;
        int preIndex = 0;
        for (int i = 1; i < price.length; i++){
            if (price[i] - price[preIndex] >= m ){
                count++;
                preIndex = i;
            }
        }
        return count >= k;
    }
}

image.png

目录
相关文章
欧拉筛(最优的方法,对于找质数,细节讲解)
欧拉筛(最优的方法,对于找质数,细节讲解)
140 0
|
6月前
线性代数——(期末突击)概率统计习题(概率的性质、全概率公式)
线性代数——(期末突击)概率统计习题(概率的性质、全概率公式)
58 1
|
6月前
|
搜索推荐 算法 C++
蓝桥杯分糖果、最小化战斗力差距、小蓝零花钱
这是一个关于算法问题的集合,包括三个不同的任务: 1. **分糖果**:肖恩有不同种类的糖果要分给学生,目标是使得到糖果字符串的字典序最大且尽量小。给定糖果种类数和一个初始字符串,输出能达到的最小字典序的最大值。 2. **最小化战斗力差距**:小蓝需要将队员分为两组,每组战斗力差距最小。给定队员数量和战斗力值,找出最小的战斗力差距。 3. **小蓝的零花钱**:小蓝要在序列中分割偶数和奇数,每次分割代价是两端元素差的绝对值。目标是在预算内确定最多能进行多少次这样的分割。 每个问题都提供了输入输出示例和相应的C++代码片段来解决这些问题。
|
7月前
|
人工智能 BI 测试技术
【图论】【树形dp】【深度优先搜索】2538. 最大价值和与最小价值和的差值
【图论】【树形dp】【深度优先搜索】2538. 最大价值和与最小价值和的差值
|
7月前
考研高数之无穷级数题型一:判断收敛性、求收敛半径以及收敛域和收敛区间(题目讲解)
考研高数之无穷级数题型一:判断收敛性、求收敛半径以及收敛域和收敛区间(题目讲解)
444 0
|
机器学习/深度学习 算法 数据处理
无约束最优化(五) 最小二乘法问题的解法
无约束最优化(五) 最小二乘法问题的解法
190 0
|
机器学习/深度学习 算法
非凸函数上,随机梯度下降能否收敛?网友热议:能,但有条件,且比凸函数收敛更难
非凸函数上,随机梯度下降能否收敛?网友热议:能,但有条件,且比凸函数收敛更难
|
人工智能 开发者
泰勒公式出发点 | 学习笔记-
快速学习泰勒公式出发点
1005. K 次取反后最大化的数组和 : 简单分情况讨论贪心模拟题
1005. K 次取反后最大化的数组和 : 简单分情况讨论贪心模拟题