题目链接:环形最大子段和
给定一个长度为 的环形数组 ,其中 和 首尾相接, 相邻的下一个元素是 , 相邻的上一个元素是 。现在我们想在环形数组 , 取连续且非空的一段,那么这段的和最大是多少?
限制:
算法分析
本题难度中等,考察枚举及前缀和的技巧。
和最大的子段在数组 中只有两种情况:
- 最大子段包含的元素不同时在数组 两端
- 最大子段同时包含数组 两端的元素,即 和
第一种情况,说明最大子段和就是数组 的最大子段和;第二种情况,最大子段和为 的所有元素总和 -
的最小子段和
在以上两种情况下的结果的最大值即为最终答案。
也就是说,需要计算数组 的最大子段和与最小子段和,这里以最大子段和为例:
50分做法: 双重循环枚举终点 和起点 ,然后再利用循环计算 ,同时更新最大值。该算法的时间复杂度为 。
70分做法: 在 分做法的基础上可以利用前缀和计算 。该算法的时间复杂度为 。
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; inline void chmin(int& x, int y) { if (x > y) x = y; } inline void chmax(int& x, int y) { if (x < y) x = y; } int main() { int n; cin >> n; vector<int> a(n); rep(i, n) cin >> a[i]; vector<int> s(n+1); rep(i, n) s[i+1] = s[i]+a[i]; int maxS = -2e9, minS = 2e9; for (int i = 1; i <= n; ++i) { for (int j = i; j <= n; ++j) { int now = s[j]-s[i-1]; chmin(minS, now); chmax(maxS, now); } } int ans = max(maxS, s[n]-minS); cout << ans << '\n'; return 0; }
100分做法: 在 分做法中,内层循环的作用为在 固定不变的情况下找 的最大值。 等价于 ,可以预处理得到 就可以砍掉一重循环。假设 mins
表示前缀和数组 的前 个元素的最小值,maxs
表示前缀和数组 的前 个元素的最大值。
该算法的时间复杂度为 。
但这样还是有问题:
hack数据:
in 3 -3 -2 -3 out -2
我们还需特判一下这种 等于 的情况,答案应该为线形的最大子段和。
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; inline void chmin(int& x, int y) { if (x > y) x = y; } inline void chmax(int& x, int y) { if (x < y) x = y; } int main() { int n; cin >> n; vector<int> a(n); rep(i, n) cin >> a[i]; vector<int> s(n+1); rep(i, n) s[i+1] = s[i]+a[i]; vector<int> mins(n+1), maxs(n+1); for (int i = 1; i <= n; ++i) { mins[i] = min(mins[i-1], s[i]); maxs[i] = max(maxs[i-1], s[i]); } int maxS = -2e9, minS = 2e9; for (int i = 1; i <= n; ++i) { chmin(minS, s[i]-maxs[i-1]); chmax(maxS, s[i]-mins[i-1]); } int ans = max(maxS, s[n]-minS); if (s[n]-minS == 0) ans = maxS; cout << ans << '\n'; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现