最大连续子序列(暑假每日一题 27)
原创
©著作权归作者所有:来自51CTO博客作者sweetheart7_7的原创作品,请联系作者获取转载授权,否则将追究法律责任
给定 个整数的序列 ,其任意连续子序列可表示为 ,其中 。
最大连续子序列是所有连续子序列中元素和最大的一个,例如给定序列 ,其最大连续子序列为 ,最大和为 。
编写程序得到其中最大子序列的和并输出该子序列的第一个和最后一个元素的下标。
输入格式
输入包含多组测试数据。
每组数据占 行,第 行给出正整数 。
第 行给出 个整数 。
输出格式
每组数据输出一行结果,包含最大子序列的和以及子序列的第一个下标 和最后一个元素的下标 。
所有元素下标为 。
如果最大子序列不唯一,则选择 最小的那个子序列,如果仍不唯一,则选择 最小的子序列中
若所有 个元素都是负数,则定义其最大和为 0
,输出 0 0 0
。
数据范围
输入最多包含
输入样例:
8
6 -2 11 -4 13 -5 -2 10
5
10 -10 10 -10 10
8
-1 -5 -2 3 -1 0 -2 0
4
-1 -2 -4 -3
输出样例:
DP问题
- 状态表示 f[i] 代表以 i 为右端点的区间
- 属性 max
- 状态计算:f[i] = max(w[i], w[i] + f[i - 1])
#include<iostream>
using namespace std;
const int N = 100010;
int n;
int q[N];
int main(){
while(~scanf("%d", &n)){
for(int i = 0; i < n; i++)
scanf("%d", &q[i]);
int res = 0, l = 0, r = 0;
// f 表示以i为左端点的区间最大连续和
// g 表示以i为左端点的区间最大连续和对应的最左边的区间右端点
for(int i = n - 1, f = 0, g = n - 1; i >= 0; i--){
if(f <= 0){
f = 0;
g = i;
}
f += q[i];
if(f >= res){
res = f;
l = i;
r = g;
}
}
printf("%d %d %d\n", res, l, r);
}
return 0;
}