#include <stdio.h>
int main()
{
int a[110000], dp[110000];
int i, j, k, t, n, begin, end, temp, max;
scanf("%d", &t); //共有t组测试实例。
for(k=1; k<=t; k++)
{
scanf("%d", &n);
for(i=1; i<=n; i++)
scanf("%d", &a[i]);
dp[1] = a[1]; //dp[i]数组存放的是,以i为终点的最大子序列和。
begin = 1; //begin end记录起始与结尾下标。
end = 1;
temp = 1; //重点:记录每个重新开始的子序列的起始下标。(后面会详细介绍)
max = dp[1]; //max 存放 和最大子序列。
for(i=2; i<=n; i++)
{
if(a[i] > dp[i-1]+a[i]) //状态转移方程:dp[i] = max(dp[i-1]+a[i] , a[i]) 是指取二者中的最大值。
{
dp[i] = a[i];
temp = i; //temp 当a[i] > dp[i-1]+a[i]成立时dp[i]的开始下标会更新。
}
else
dp[i] = dp[i-1] + a[i];
if(dp[i] > max)
{
max = dp[i];
end = i;
begin = temp;
}
}
printf("Case %d:\n%d %d %d\n", k, max, begin, end);
if(k!=t) //注意格式问题。
printf("\n");
}
return 0;
}
/*******************************************************************************************************
这是一道典型的动态规划题(DP),下面以一实例进一步解释。如序列{6,-1,-3,-1,6,8}
dp[1] = 6, dp[2] = 5(因为dp[1]+a[1] > a[1],下面也是一样), dp[3] = 2, dp[4] = 1, dp[5] = 7, dp[6] = 15.
begin = 1, end = 6.
DP问题中最关键的是找到状态转移方程。这题状态转移方程为dp[i] = max(dp[i-1]+a[i] , a[i])
若仍然不太理解 加我QQ:836939432
********************************************************************************************************/
/* ********************************************
作者:桂思
时间:2013年12月7日 20:04:42
用途:求和最大子序列。
******************************************** */
浙公网安备 33010602011771号