LCP 33. 蓄水

题目链接

LCP 33. 蓄水 easy

题目描述

给定 N 个无限容量且初始均空的水缸,每个水缸配有一个水桶用来打水,第 i 个水缸配备的水桶容量记作 b u c k e t [ i ] bucket[i] bucket[i]。小扣有以下两种操作:

  • 升级水桶:选择任意一个水桶,使其容量增加为 b u c k e t [ i ] + 1 bucket[i]+1 bucket[i]+1
  • 蓄水:将全部水桶接满水,倒入各自对应的水缸

每个水缸对应最低蓄水量记作 v a t [ i ] vat[i] vat[i],返回小扣至少需要多少次操作可以完成所有水缸蓄水要求。

注意:实际蓄水量 达到或超过 最低蓄水量,即完成蓄水要求。

示例 1:

输入:bucket = [1,3], vat = [6,8]

输出:4

解释: 第 1 次操作升级 bucket[0]; 第 2 ~ 4 次操作均选择蓄水,即可完成蓄水要求。

示例 2:

输入:bucket = [9,0,1], vat = [0,2,2]

输出:3

解释: 第 1 次操作均选择升级 bucket[1] 第 2~3 次操作选择蓄水,即可完成蓄水要求。

提示:
  • 1 < = b u c k e t . l e n g t h = = v a t . l e n g t h < = 100 1 <= bucket.length == vat.length <= 100 1<=bucket.length==vat.length<=100
  • 0 < = b u c k e t [ i ] , v a t [ i ] < = 1 0 4 0 <= bucket[i], vat[i] <= 10^4 0<=bucket[i],vat[i]<=104

解法:贪心

我们注意到 蓄水的次数 其实是固定的。所以我们可以直接枚举 蓄水的次数( m a x k = m a x { v a t [ i ] } maxk = max \{ vat[i] \} maxk=max{vat[i]}),如果我们每次蓄水的量是 1 的话,故装满需要 m a x k maxk maxk 次。

接着我们枚举 k k k 1 ≤ k ≤ m a x k 1 \leq k \leq maxk 1kmaxk),在总的蓄水次数为 k k k 的情况下,每一个桶的容量应该是 c = ( v a t [ i ] + k − 1 ) / k c = (vat[i] + k - 1)/k c=(vat[i]+k1)/k,将 c c c 将去其本来的容量 b u c k e t [ i ] bucket[i] bucket[i] 就是这个桶需要升级的次数 d d d,即 d = m a x { c − b u c k e t [ i ] , 0 } d = max \{c - bucket[i] , 0 \} d=max{cbucket[i],0}(因为 c − b u c k e t [ i ] c - bucket[i] cbucket[i] 可能 < 0 <0 <0)。

接着把总的蓄水次数 k k k + 每一个水桶的升级次数 d d d 就是总的操作次数。我们只要取其中的最小值即可。

时间复杂度: O ( n × m a x k ) O(n \times maxk) O(n×maxk)

C++代码:


class Solution {
public:
    int storeWater(vector<int>& bucket, vector<int>& vat) {
        int maxk = *max_element(vat.begin(),vat.end());
        if(maxk == 0) return 0;

        int n = bucket.size();

        int ans = 1e9;
        //k 是总共需要蓄水的次数
        for(int k = 1;k <= maxk;k++){
            int t = k;
            for(int i = 0;i < n;i++){
                //c 是当蓄水次数为k的清空下,能够装满水的 bucket[i] 的最小容量
                int c = (vat[i] + k - 1) / k;
                //c - bucket[i] 就是需要升级水桶的次数,因为可能为负数,所以 max(c - bucket[i],0)
                t += max(c - bucket[i] , 0);
            }
            ans = min(ans,t);
        }
        return ans;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值