LCCUP 力扣杯 蓄水

题目


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

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

每个水缸对应最低蓄水量记作 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 <= bucket.length == vat.length <= 100
  • 0 <= bucket[i], vat[i] <= 10^4

 

思路


这题有一个比较重要的地方,在于除法的向上取整

比如 vat = 9 但是 bucket = 4 的时候,还是得装3次。

大佬的思路是,将问题思路转变为,如果我要 i 次装满所有的水缸,我各个位置的水桶都需要多大才行,即(bucket)的大小。

比如当 i = 1 的时候,即为倒一次水即可全部装满。就以实例1来说,那么,一次装满水,vat[0] = 6bucket[0] = 1,所以相除,需要的bucket大小为6,原本为1,所以需要5次(6 - 1)扩容机会。vat[1] = 8, bucket[1] = 3,所以需要的bucket大小为8,需要5次扩容机会。总扩容次数为10次,装水次数为1,总操作次数为11。

当 i = 2 时,即为倒一次水即可全部装满。那么,两次次装满水,相除得到3,说明需要的bucket大小为3,原本为1,所以需要(3 - 2)扩容机会。第二个桶,相除等于4(8 / 2),所以需要扩容(4 - 3)次,即为1次。总扩容次数为2次,装水次数为2,总操作次数为4。

以此类推当操作次数高到一定程度的时候,扩容次数就慢慢少下来了,通过遍历的方法记录最小值即为答案。

 

代码


class Solution {
public:
    int storeWater(vector<int>& bucket, vector<int>& vat) {
        int ans=1e9;
        if(*max_element(vat.begin(),vat.end())==0)return 0;    // 都为0即返回0
        for(int i=1;i<=10000;++i){    // i为装水次数,遍历至10000(题目限制)
            int n=vat.size(),sum=i;   // sum为操作次数,所以一开始要加上i装水次数
            for(int j=0;j<n;++j){
                // vat / i 为每个桶需要的大小,减去原来的大小即为扩容次数
                // 但是要记住刚刚说到的向上取整的问题,即 9 / 4 应该等于3
                // 所以 vat[j] + i - 1 即为向上取整
                sum+=max(0,(vat[j]+i-1)/i-bucket[j]);   
            }
            ans=min(ans,sum);    // 每次记录操作最小值
        }
        return ans;
    }
};

注意:

为什么 vat[j] + i - 1 / i 是向上取整,就比如举个例子

3 / 3 = 1

int计算默认是向下取整,那么 (3 + 2) / 3 = 1 没有影响结果

而在 2 / 3 = 0,而我们实际想要的结果为 1 , 所以 ( 2 + 2 ) / 3 = 1,那为什么不是 i 而是 i - 1,因为 ( 3 + 3 ) / 3 = 2 已经产生了错误的答案

 

最后

希望自己算法能力越来越好~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值