题目链接
思路
设 f [ i ] f[i] f[i] 为以 i i i 结尾的最大连续字段和。
转移方程: f [ i ] = m a x ( f [ i ] + a [ i ] , a [ i ] ) ( 1 ≤ i ≤ n ) f[i]=max(f[i]+a[i],a[i])(1 \le i \le n) f[i]=max(f[i]+a[i],a[i])(1≤i≤n)
在计算 f [ i ] f[i] f[i] 的同时,需要记录一下连续字段和的起始位置。
代码
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <bitset>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#define LL long long
#define mem(a, b) memset(a, b, sizeof a)
#define lowbit(x) (-x&x)
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define endl '\n'
#define rev(x) reverse(x.begin(), x.end())
#define INF 0x3f3f3f3f
using namespace std;
const int N = 100010;
int n;
int a[N];
int f[N], g[N];
void solve() {
int tt;
cin >> tt;
int T = 1;
while (tt -- ) {
cin >> n;
for (int i = 1; i <= n; i ++ ) {
cin >> a[i];
f[i] = 0;
g[i] = i;
}
int st = 1, ans = -INF;
for (int i = 1; i <= n; i ++ ) {
if (a[i] > f[i - 1] + a[i]) {
f[i] = a[i];
st = i;
} else {
f[i] = f[i - 1] + a[i];
g[i] = st;
}
}
int maxid;
for (int i = 1; i <= n; i ++ ) ans = max(ans, f[i]);
for (int i = 1; i <= n; i ++ ) {
if (ans == f[i]) {
maxid = i;
break;
}
}
printf("Case %d:\n", T ++ );
printf("%d %d %d\n", ans, g[maxid], maxid);
if (tt) puts("");
}
}
int main() {
IOS;
solve();
return 0;
}