题目描述:
给定K个整数的序列{N1, N2, ...,NK },其任意连续子序列可表示为{Ni,Ni+1,...,Nj},其中1<=i<=j<= K。最大连续子序列是所有连续子序列中元素和最大的一个,例如给定序列{ -2,11,-4,13,-5,-2},其最大连续子序列为{11,-4,13 },最大和为20。编写程序得到其中最大子序列的和并输出该子序列的第一个和最后一个元素的下标。
根据题目绘制绘制动态转移方程:
dp[i]=max{dp[i]-1+arr[i],arr[i]}:若前面子序列<=0则根据最短原则,就选择第i个数为自身的子序列
代码:
#include <iostream> #include <stdio.h> using namespace std; typedef long long ll; int arr[100001], dp[100001]; bool Max(int a, int b) { return a > b; } int main() { int k; while (scanf("%d", &k) != EOF) { int start = 0, end = 0; for (int i = 0; i < k; i++) { scanf("%d", &arr[i]); } ll max = 0; dp[0] = arr[0]; int temp = 0; for (int i = 1; i < k; i++) { /*考虑自身为序列 后面会出现更大值 用temp暂存索引 若序列增加超过max时 开始索引为temp */ if (Max(arr[i], dp[i - 1] + arr[i])) { if (max < arr[i]) { max = arr[i]; start = i; end = i; } temp=i; dp[i] = arr[i]; } else { dp[i] = dp[i - 1] + arr[i]; if (max < dp[i]) { start=temp; max = dp[i]; end = i; } } } if (max < 0) { start = end = max = 0; } printf("%ld %d %d ", max, start, end); } }