POJ 2479 Maximum sum
算法核心:dp
对于n个连续数字,在其中任意取出两个不重叠的连续段,求所有合法条件下该两个连续段和的最大值
例如:
n = 10,数字为:1 -1 2 2 3 -3 4 -4 5 -5
此时答案为13 ,即(2,2,3,-3,4)与(5)的和
#include
<
stdio.h
>
const int N = 50000 + 1 ;
int dp1[ 2 ]; // dp[i]记录包含数字i的前i个数字的一段最大和
int dp2[ 2 ]; // dp2[i]记录前i个数字的一段最大和
int dp3[ 2 ]; // dp3[i]记录到包含数字i的两段最大和
inline int max( int a, int b)
{
return a > b ? a:b;
}
int main()
{
int T;
while (scanf( " %d " , & T) != EOF)
{
while (T -- )
{
int n,i,a;
scanf( " %d " , & n);
scanf( " %d " , & a);
dp1[ 0 ] = a;
dp2[ 0 ] = a
const int N = 50000 + 1 ;
int dp1[ 2 ]; // dp[i]记录包含数字i的前i个数字的一段最大和
int dp2[ 2 ]; // dp2[i]记录前i个数字的一段最大和
int dp3[ 2 ]; // dp3[i]记录到包含数字i的两段最大和
inline int max( int a, int b)
{
return a > b ? a:b;
}
int main()
{
int T;
while (scanf( " %d " , & T) != EOF)
{
while (T -- )
{
int n,i,a;
scanf( " %d " , & n);
scanf( " %d " , & a);
dp1[ 0 ] = a;
dp2[ 0 ] = a
scanf(
"
%d
"
,
&
a);
dp1[ 1 ] = max(dp1[ 0 ] + a,a);
dp2[ 1 ] = max(dp1[ 1 ],dp2[ 0 ]);
dp3[ 1 ] = dp1[ 0 ] + a;
int pre = 0 ;
int cur = 1 ;
int ans = dp3[ 1 ];
for (i = 2 ;i < n;i ++ )
{
cur = pre;
pre = 1 - pre;
scanf( " %d " , & a);
dp1[cur] = max(dp1[pre] + a,a);
dp2[cur] = max(dp2[pre],dp1[cur]);
dp3[cur] = max(dp3[pre] + a,dp2[pre] + a);
ans = max(dp3[cur],ans);
}
printf( " %d\n " ,ans);
}
}
return 0 ;
}
dp1[ 1 ] = max(dp1[ 0 ] + a,a);
dp2[ 1 ] = max(dp1[ 1 ],dp2[ 0 ]);
dp3[ 1 ] = dp1[ 0 ] + a;
int pre = 0 ;
int cur = 1 ;
int ans = dp3[ 1 ];
for (i = 2 ;i < n;i ++ )
{
cur = pre;
pre = 1 - pre;
scanf( " %d " , & a);
dp1[cur] = max(dp1[pre] + a,a);
dp2[cur] = max(dp2[pre],dp1[cur]);
dp3[cur] = max(dp3[pre] + a,dp2[pre] + a);
ans = max(dp3[cur],ans);
}
printf( " %d\n " ,ans);
}
}
return 0 ;
}