🌟 P3009 [USACO11JAN] Profits S - Kadane算法解法
解题思路
计算整数序列的最大连续子段和。使用Kadane算法在O(n)时间复杂度和O(1)空间复杂度内高效解决该问题。
核心算法思想
状态定义
- current_sum:以当前元素结尾的最大子段和
- max_sum:全局最大子段和
状态转移方程
\begin{cases}
\text{current\_sum} = \max(\text{profit}, \text{current\_sum} + \text{profit}) \\
\text{max\_sum} = \max(\text{max\_sum}, \text{current\_sum})
\end{cases}
边界处理
- 全负数序列:返回最大的单个负数
- 单元素序列:直接返回该元素值
代码实现
#include <iostream>
#include <algorithm>
#include <climits>
using namespace std;
int main() {
int n;
cin >> n;
long long current_sum = 0;
long long max_sum = LLONG_MIN; // 初始化为最小整数
for (int i = 0; i < n; i++) {
long long profit;
cin >> profit;
current_sum = max(profit, current_sum + profit);
max_sum = max(max_sum, current_sum);
}
cout << max_sum << endl;
return 0;
}
算法优化点
1. 高效状态转移
- 智能决策:选择以当前元素重新开始或延续之前的子段
- 常数时间更新:每个元素仅需O(1)时间处理
2. 边界处理优化
- LLONG_MIN初始化:正确处理全负数序列
- 动态更新:不依赖序列值域范围
3. 空间优化
- 双变量维护:仅需
current_sum和max_sum两个变量 - 内存友好:支持处理n≤1e6的大数据
复杂度分析
| 维度 | 分析说明 |
|---|---|
| 时间复杂度 | O(n) ,单次遍历所有元素 |
| 空间复杂度 | O(1) ,仅需两个变量 |
算法演示
样例输入:[-3, 4, 9, -2, -5, 8, -3]
| 元素 | current_sum | max_sum |
|---|---|---|
| -3 | -3 | -3 |
| 4 | 4 | 4 |
| 9 | 13 | 13 |
| -2 | 11 | 13 |
| -5 | 6 | 13 |
| 8 | 14 | 14 |
| -3 | 11 | 14 |
输出:14(对应子序列[4,9,-2,-5,8])
特殊情况处理
| 情况 | 处理方式 | 结果示例 |
|---|---|---|
| 全正序列 | 返回序列总和 | [5,9,3] → 17 |
| 全负序列 | 返回最大单个元素 | [-3,-9] → -3 |
| 单元素序列 | 直接返回该元素 | [7] → 7 |
| 含零序列 | 零可包含在最优解中 | [-1,0,-2] → 0 |
算法特点
- 线性效率:完美处理百万级数据规模
- 代码简洁:核心逻辑仅5行代码
- 健壮性强:正确处理各类边界情况
- 通用性广:适用于股票分析、信号处理等场景
测试验证:已通过洛谷所有测试用例,包括全负数和极大值测试。
Sanhai AI
852

被折叠的 条评论
为什么被折叠?



