题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003
题目大意:
求解一个序列的最大字段和,已经最前面的那个最大子段的起止坐标。
解题思路:
定义状态 \(f[i]\) 为以 \(a[i]\) 结尾的最大字段和,则有状态转移方程:
\[f[i] = \max(0, f[i-1]) + a[i]\]
同时定义状态 \(s[i]\) 表示以 \(a[i]\) 结尾的最大字段的最左边元素的坐标,则有:
- 当 \(f[i] \lt 0\) 时,\(s[i] = i\);
- 当 \(f[i] \ge 0\) 时,\(s[i] = s[i-1]\)
实现代码如下:
#include <bits/stdc++.h> using namespace std; const int maxn = 100010; int T, n, a[maxn], f[maxn], anss, anst, s[maxn], ans; int main() { scanf("%d", &T); for (int cas = 1; cas <= T; cas ++) { if (cas > 1) puts(""); scanf("%d", &n); for (int i = 1; i <= n; i ++) scanf("%d", a+i); ans = f[1] = a[1]; anss = anst = s[1] = 1; for (int i = 2; i <= n; i ++) { if (f[i-1] >= 0) { f[i] = f[i-1] + a[i]; s[i] = s[i-1]; } else { f[i] = a[i]; s[i] = i; } if (f[i] > ans) { ans = f[i]; anss = s[i]; anst = i; } } printf("Case %d:\n", cas); printf("%d %d %d\n", ans, anss, anst); } return 0; }
来源:https://www.cnblogs.com/quanjun/p/12189728.html