C++前缀和算法的应用:最大化城市的最小供电站数目(一)

简介: C++前缀和算法的应用:最大化城市的最小供电站数目

本文涉及的基础知识点

C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频

二分法

题目

给你一个下标从 0 开始长度为 n 的整数数组 stations ,其中 stations[i] 表示第 i 座城市的供电站数目。

每个供电站可以在一定 范围 内给所有城市提供电力。换句话说,如果给定的范围是 r ,在城市 i 处的供电站可以给所有满足 |i - j| <= r 且 0 <= i, j <= n - 1 的城市 j 供电。

|x| 表示 x 的 绝对值 。比方说,|7 - 5| = 2 ,|3 - 10| = 7 。

一座城市的 电量 是所有能给它供电的供电站数目。

政府批准了可以额外建造 k 座供电站,你需要决定这些供电站分别应该建在哪里,这些供电站与已经存在的供电站有相同的供电范围。

给你两个整数 r 和 k ,如果以最优策略建造额外的发电站,返回所有城市中,最小供电站数目的最大值是多少。

这 k 座供电站可以建在多个城市。

示例 1:

输入:stations = [1,2,4,5,0], r = 1, k = 2

输出:5

解释:

最优方案之一是把 2 座供电站都建在城市 1 。

每座城市的供电站数目分别为 [1,4,4,5,0] 。

  • 城市 0 的供电站数目为 1 + 4 = 5 。
  • 城市 1 的供电站数目为 1 + 4 + 4 = 9 。
  • 城市 2 的供电站数目为 4 + 4 + 5 = 13 。
  • 城市 3 的供电站数目为 5 + 4 = 9 。
  • 城市 4 的供电站数目为 5 + 0 = 5 。
    供电站数目最少是 5 。
    无法得到更优解,所以我们返回 5 。
    示例 2:
    输入:stations = [4,4,4,4], r = 0, k = 3
    输出:4
    解释:
    无论如何安排,总有一座城市的供电站数目是 4 ,所以最优解是 4 。
    参数范围
    n == stations.length
    1 <= n <= 105
    0 <= stations[i] <= 105
    0 <= r <= n - 1
    0 <= k <= 109

分析

时间复杂度

O(nlogm),m= sum(stations)+k。

第一层循环

如果任何城市的最小供电站数大于等于llTarget,则任何城市的最小供电站数一定llTarget-1,如果有多个满足条件的,我们返回最后一个。显然用左闭右开的二分。极限情况下能有多少供电站?所有供电站(已建和可建的)都可以供应所有城市。

第二层循环

当前城市供电站不足的时候,在right城市建立足够的供电站。

变量说明

i 当前城市
llTarget 让所有城市至少有iTarget个供电站
llNeed 让所有城市至少有iTarget个供电站,需要新建多少个供电站
stations 各城市供电站(新建、已有)之和
llHas 能给当前城市供电的供电站,包括处理之前城市而建立的供电站
left 给当前城市供电的最左城市
right 能给当前城市供电的最右城市

注意

r可以大于stations.size()

代码

核心代码

class Solution {
public:
  long long maxPower(vector<int>& stations, int r, int k) {
    m_iR = r;
    m_iK = k;
    m_stations = stations;
    long long left = 0, right = std::accumulate(stations.begin(), stations.end(),0LL) + k + 1;
    //左闭右开
    while (right - left > 1)
    {
      const long long mid = left + (right - left) / 2;
      if (TargetNeed(mid))
      {
        left = mid;
      }
      else
      {
        right = mid;
      }
    }
    return left;
  }
  //所有城市供电站达到iTarget,需要新建多少供电站
  bool TargetNeed(long long llTarget)
  {
    vector<int> stations = m_stations;
    long long llHas = 0;
    int left = 0;
    int right = min(m_iR, (int)stations.size() - 1);//[left,right]表示能够给此城市供电的电站
    for (int i = 0; i <= right; i++)
    {
      llHas += stations[i];
    }
    long long llNeed = 0;   
    auto Add = [&]()
    {
      const long long curNeed = llTarget - llHas;
      if (curNeed > 0)
      {
        llNeed += curNeed;
        if (llNeed > m_iK)
        {
          return false;
        }
        stations[right] += curNeed;
        llHas += curNeed;
      }
      return true;
    };
    if (!Add())
    {
      return false;
    }
    for (int i = 1; i < stations.size(); i++)
    {
      if (i - left > m_iR)
      {       
        llHas -= stations[left];
        left++;
      }
      if (right+1 < stations.size())
      {
        right++;
        llHas += stations[right];
      }
      if (!Add())
      {
        return false;
      }
    }
    return true;
  }
  int m_iR;
  int m_iK;
  vector<int> m_stations;
};

测试用例

template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
assert(v1[i] == v2[i]);
}
}
template
void Assert(const T& t1, const T& t2)
{
assert(t1 == t2);
}
int main()
{
Solution slu;
vector stations = { 1, 2, 4, 5, 0 };
int r = 0;
int k = 0;
long long res;
stations = { 1, 2, 4, 5, 0 };
r = 1, k = 2;
res = slu.maxPower(stations, r, k);
Assert(5LL, res);
stations = {1 };
r = 0, k = 3;
res = slu.maxPower(stations, r, k);
Assert(4LL, res);
stations = { 0 };
r = 0, k = 0;
res = slu.maxPower(stations, r, k);
Assert(0LL, res);
stations = { 4, 4, 4, 4 };
r = 0, k = 3;
res = slu.maxPower(stations, r, k);
Assert(4LL, res);
stations.assign(2, 1);
r = 1;
k = 1;
res = slu.maxPower(stations, r, k);
Assert(3LL, res);
stations.assign(100000, 100000);
r = 100000;
k = 1e9;
res = slu.maxPower(stations, r, k);
Assert(long long(1e10+1e9+0.5), res);
//CConsole::Out(res);
}


相关文章
|
8月前
|
存储 监控 JavaScript
基于布隆过滤器的 Node.js 算法在局域网电脑桌面监控设备快速校验中的应用研究
本文探讨了布隆过滤器在局域网电脑桌面监控中的应用,分析其高效空间利用率、快速查询性能及动态扩容优势,并设计了基于MAC地址的校验模型,提供Node.js实现代码,适用于设备准入控制与重复数据过滤场景。
297 0
|
7月前
|
运维 监控 JavaScript
基于 Node.js 图结构的局域网设备拓扑分析算法在局域网内监控软件中的应用研究
本文探讨图结构在局域网监控系统中的应用,通过Node.js实现设备拓扑建模、路径分析与故障定位,提升网络可视化、可追溯性与运维效率,结合模拟实验验证其高效性与准确性。
410 3
|
7月前
|
机器学习/深度学习 资源调度 算法
遗传算法模型深度解析与实战应用
摘要 遗传算法(GA)作为一种受生物进化启发的优化算法,在复杂问题求解中展现出独特优势。本文系统介绍了GA的核心理论、实现细节和应用经验。算法通过模拟自然选择机制,利用选择、交叉、变异三大操作在解空间中进行全局搜索。与梯度下降等传统方法相比,GA不依赖目标函数的连续性或可微性,特别适合处理离散优化、多目标优化等复杂问题。文中详细阐述了染色体编码、适应度函数设计、遗传操作实现等关键技术,并提供了Python代码实现示例。实践表明,GA的成功应用关键在于平衡探索与开发,通过精心调参维持种群多样性同时确保收敛效率
|
7月前
|
机器学习/深度学习 边缘计算 人工智能
粒子群算法模型深度解析与实战应用
蒋星熠Jaxonic是一位深耕智能优化算法领域多年的技术探索者,专注于粒子群优化(PSO)算法的研究与应用。他深入剖析了PSO的数学模型、核心公式及实现方法,并通过大量实践验证了其在神经网络优化、工程设计等复杂问题上的卓越性能。本文全面展示了PSO的理论基础、改进策略与前沿发展方向,为读者提供了一份详尽的技术指南。
粒子群算法模型深度解析与实战应用
|
7月前
|
机器学习/深度学习 算法 安全
小场景大市场:猫狗识别算法在宠物智能设备中的应用
将猫狗识别算法应用于宠物智能设备,是AIoT领域的重要垂直场景。本文从核心技术、应用场景、挑战与趋势四个方面,全面解析这一融合算法、硬件与用户体验的系统工程。
654 0
|
9月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习模型、算法与应用的全方位解析
深度学习,作为人工智能(AI)的一个重要分支,已经在多个领域产生了革命性的影响。从图像识别到自然语言处理,从语音识别到自动驾驶,深度学习无处不在。本篇博客将深入探讨深度学习的模型、算法及其在各个领域的应用。
1671 3
|
9月前
|
机器学习/深度学习 人工智能 算法
AI-Compass 强化学习模块:理论到实战完整RL技术生态,涵盖10+主流框架、多智能体算法、游戏AI与金融量化应用
AI-Compass 强化学习模块:理论到实战完整RL技术生态,涵盖10+主流框架、多智能体算法、游戏AI与金融量化应用
|
9月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
558 1
|
8月前
|
算法 数据可视化
matlab版本粒子群算法(PSO)在路径规划中的应用
matlab版本粒子群算法(PSO)在路径规划中的应用
|
10月前
|
存储 机器学习/深度学习 算法
基于 C++ 的局域网访问控制列表(ACL)实现及局域网限制上网软件算法研究
本文探讨局域网限制上网软件中访问控制列表(ACL)的应用,分析其通过规则匹配管理网络资源访问的核心机制。基于C++实现ACL算法原型,展示其灵活性与安全性。文中强调ACL在企业与教育场景下的重要作用,并提出性能优化及结合机器学习等未来研究方向。
265 4

热门文章

最新文章

下一篇
开通oss服务