HAUTOJ 1266: 最大子段和 河工大校赛DP
**1266: 最大子段和
题目描述
一个大小为n的数组a1到an(−10^4≤ai≤10^4)。请你找出一个连续子段,使子段长度为奇数,且子段和最大。
输入
第一行为T(1≤T≤5),代表数据组数。
之后每组数据,第一行为n(1≤n≤10^5),代表数组长度。
之后一行n个数,代表a1到an。
输出
每组数据输出一行,表示满足要求的子段和最大值
样例输入
1
4
1 2 3 4
样例输出
9**
题目很容易读懂,就不叙述题意了
主要思路:
1:数组num存储前i项连续的子段和,如果子段和num[i]小于0,则将第i项的值dp[i]存入第i项子段和num[i]中
2:数组num2存储前i项连续且长度为奇数的子段和,同时更新最大值
#include<stdio.h>
#include<string.h>
#define N 100000
int num[N+10],num2[N+10],dp[N+10];
int main()
{
int i,j,n,t,si,max;
scanf("%d",&t);
while(t--)
{
memset(num,0,sizeof(num));
memset(num2,0,sizeof(num2));
memset(dp,0,sizeof(dp));
scanf("%d",&n);
for( i = 1; i <= n; i ++)
scanf("%d",&dp[i]);
num[1] = dp[1];
/*思路步骤1*/
for( i = 2; i <= n; i ++)
{
if(num[i-1] + dp[i] < 0)
num[i] = dp[i];
else
num[i] = dp[i]+num[i-1];
}
num2[1] = num[1];
max = -10010;
si = 1;
/*思路步骤2*/
for( i = 1; i <= n; i ++)
{
if(num[i-1] + dp[i] < 0)
si = i;
if((i-si)%2 != 1)
num2[i] = num[i] ;
else
num2[i] = num[i] - dp[si];
if( max < num2[i])
max = num2[i];
}
printf("%d\n",max);
}
return 0;
}
后记:杭电的1003和这道题很类似,只不过多了一个判断长度奇偶的条件,自己优化时,导致WA的一个地方,是在判断起始条件处,改为了前i项连续且长度为奇数的子段和num2[i]是否小于0。
dp题自己现在写着很焦灼,还是得多思考+刷题,翻阅其他博客,发现还有另外一个比较好方法,等自己理解了再更。