给定 最大连续子序列(暑假每日一题 27)_数据 个整数的序列 最大连续子序列(暑假每日一题 27)_子序列_02,其任意连续子序列可表示为 最大连续子序列(暑假每日一题 27)_DP_03,其中 最大连续子序列(暑假每日一题 27)_子序列_04

最大连续子序列是所有连续子序列中元素和最大的一个,例如给定序列 最大连续子序列(暑假每日一题 27)_子序列_05,其最大连续子序列为 最大连续子序列(暑假每日一题 27)_DP_06 ,最大和为 最大连续子序列(暑假每日一题 27)_子序列_07

编写程序得到其中最大子序列的和并输出该子序列的第一个和最后一个元素的下标。

输入格式
输入包含多组测试数据。

每组数据占 最大连续子序列(暑假每日一题 27)_DP_08 行,第 最大连续子序列(暑假每日一题 27)_最大子序列_09 行给出正整数 最大连续子序列(暑假每日一题 27)_数据

最大连续子序列(暑假每日一题 27)_DP_08 行给出 最大连续子序列(暑假每日一题 27)_数据 个整数 最大连续子序列(暑假每日一题 27)_子序列_13

输出格式
每组数据输出一行结果,包含最大子序列的和以及子序列的第一个下标 最大连续子序列(暑假每日一题 27)_子序列_14 和最后一个元素的下标 最大连续子序列(暑假每日一题 27)_DP_15

所有元素下标为 最大连续子序列(暑假每日一题 27)_数据_16

如果最大子序列不唯一,则选择 最大连续子序列(暑假每日一题 27)_子序列_14 最小的那个子序列,如果仍不唯一,则选择 最大连续子序列(暑假每日一题 27)_子序列_14 最小的子序列中 最大连续子序列(暑假每日一题 27)_DP_15

若所有 最大连续子序列(暑假每日一题 27)_数据 个元素都是负数,则定义其最大和为 ​​​0​​​,输出 ​​0 0 0​​。

数据范围
最大连续子序列(暑假每日一题 27)_最大子序列_21
最大连续子序列(暑假每日一题 27)_子序列_22
输入最多包含 最大连续子序列(暑假每日一题 27)_DP_23

输入样例:

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

输出样例:

27 0 7
10 0 0
3 3 3
0 0 0

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;
}