Leetcode 2528. 最大化城市的最小电量【差分数组+二分答案+贪心】

Leetcode 2528. 最大化城市的最小电量

传送门

注意到答案具有单调性,即值越大,越能/不能满足要求;值越小,越不能/能满足要求。所以二分答案。
check答案的逻辑为 判断用k次建站机会能否达到指定的最小电力值,这里考虑贪心的去建站,即从左向右遍历站点,如果当前站点 i 需要新的电力以达到目标电力值,则在 i+r的地方建x个电力站,x为目标电力值-当前站点电力值。建站后区间[i,i+2*r] 内所有的站点都增加了x点电力,这是个区间修改操作,于是考虑用差分数组(支持O(1)区间修改)。注意及时还原当前站点的差分数组,以获取当前站点电力值。(不用担心还原了差分数组而导致区间修改失效,因为还原的部分是在当前站点的左侧部分,而需要区间修改的部分总是在右侧,不影响,所以可以做到一边还原一边差分的“神奇”操作)。


class Solution {
public:
    long long maxPower(vector<int>& stations, int r, int k) {
        vector<long long>arr(stations.size() + 2, 0);
        for(int i=0;i<stations.size();i++){
            int left=max(0,i-r);
            int right=min(i+r,static_cast<int>(stations.size()));
            arr[left]+=stations[i];
            arr[right + 1]-=stations[i];
        }

        long long left=0,right= (long long)(k)+100000ll*stations.size();
        long long ans = 0;
        while(left<=right){
            long long mid=(left+right)/2; // 二分答案 ,假设mid是最终答案,即最小电力的最大值
            if(k>=calNeed(arr,stations.size(),r,mid)){
                // k是题目允许的最大建站数量,如果够用,还可以继续放大二分的答案,即收缩二分的左端点。
                left=mid+1;
                ans=mid;
            }else{
                right=mid-1;
            }
        }
        return ans;
    }

    // 计算在指定最小电力值为now时,所需的建站数量
    long long calNeed(vector<long long> arr,int stationSize,int r,long long now) {
        long long need = 0;
        for(int i=0;i<stationSize;i++) {
            if(i>0)arr[i]+=arr[i-1]; // 还原差分数组
            if(arr[i]<now) {
                // 贪心:如果当前位置缺电力,则选择在 i+r的位置建站是最“经济实惠的”
                long long count =now-arr[i]; // 建站的数量
                // 差分数组的区间修改操作,整个区间都加上count
                arr[i]+= count;  
                arr[min(i+2*r+1,stationSize)]-=count;
                need+=count;
            }
        }
        return need; 
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值