题目链接:https://vjudge.net/problem/HDU-1003
题目大意:
给出一段序列,求出最大连续子序列之和,以及给出这段子序列的起点和终点。
解题思路:
最长连续子序列之和问题其实有很多种求解方式,这里是用时间复杂度为O(n)的动态规划来求解。
思路很清晰,用dp数组来表示前i项的最大连续子序列之和,如果dp[i-1]>=0的话,则dp[i]加上dp[i-1]能够使dp[i]增大;若dp[i-1]<0的话,则重新以dp[i]为起点,起点更新。
#include <cstdio> int main() { int t, n, i, j, cas = 0; scanf("%d", &t); while (t--) { int dp[100010]; //dp数组表示以i为终点的最大连续子序列之和 scanf("%d", &n); for (i = 1; i <= n; i++)scanf("%d", &dp[i]); dp[0] = -1; int max = -0x3f3f3f3f; int s=1,start=1, e; for (i = 1; i <= n; i++) { if (dp[i - 1] >= 0)dp[i] = dp[i - 1] + dp[i]; //若dp[i-1]>=0,则第i个数直接在原基础上相加 else s = i; //否则的话,以第i个数为起点重新相加 if (max < dp[i]) { max = dp[i]; e = i; //记录下此时的终点 start = s; //记录下此时的起点,要注意不要将start与s混淆,s只是为每一段的起点,而start才是当前所遇到的连续子序列和最大的起点 } } printf("Case %d: ", ++cas); printf("%d %d %d ", max, start, e); if (t)printf(" "); } return 0; }
2018-04-30