力扣2528.最大化城市的最小电量
-
二分答案 + 前缀和 + 差分 + 贪心
- 用前缀和把每个点的电量求出
- 二分答案
- 遍历数组,若电量不够则在i+r处放发电站,即在[i,i+2*r]区间内+1
-
class Solution { public: long long maxPower(vector<int>& stations, int r, int k) { int n = stations.size(); long sum[n+1],power[n],dif[n]; sum[0] = 0; for(int i=0;i<n;i++) //前缀和 sum[i+1] = sum[i] + stations[i]; for(int i=0;i<n;i++) power[i] = sum[min(i+r+1,n)] - sum[max(i-r,0)]; auto check = [&](long min_power) -> bool{ //重置差分数组 memset(dif,0,sizeof(dif)); long sum_d = 0,need = 0; for(int i=0;i<n;i++) { //累积差分和,其意义为当前位置新增的电量 sum_d += dif[i]; //需要建几个电站 long m = min_power - power[i] - sum_d; if(m > 0) { need += m; if(need > k) return false; //新增m电量 sum_d += m; //[i,i+2r]区间+1 if(i + 2*r +1 < n) dif[i+2*r+1] -= m; } } return true; }; long left = *min_element(power, power + n), right = left + k; // 开区间写法 while (left < right) { long mid = (left + right + 1)/ 2; check(mid) ? left = mid: right = mid - 1; } return left; } };