您的位置:首页 > 其它

poj 2479解题报告

2010-10-06 21:02 344 查看
有意识做的第一道DP,思路还不是自己想出来的。一开始从最大子序列想起,因为之前做过一道,但发现这道题是求两个最大子序列的值之和,而且各自序列的元素不能有重叠。想了一下,没什么idea,结果很没耐心地看了discuss zone。 看到了一个0(n)的思路,豁然开朗,于是立马下去敲,敲完后submit。结果WA~~~后来查了下代码,把int换成__int64, 结果就过了。其实应该是不会超int的啊,很奇怪O_O

大概思路是这样的,定义两个数组l[],r[]。l[]存储从左开始各个位置的最大连续子序列的值,如l[k]表示从0-k中最大的子序列值,注意:k不一定包含其中。r[]则从右边处理,思路一样。然后遍历一遍,找出最大的l[i]+r[i+1]即可。

贴下代码:

#include<cstdio>
#include<iostream>
using namespace std;
int a[50002];
__int64 l[50002];
__int64 r[50002];
int max( __int64 l, __int64 r )
{
return l > r ? l : r;
}
int main()
{
int t;
scanf("%d",&t);
int n;
for( int i=0; i<t; i++ )
{
scanf( "%d",&n );
int j;
for( j=0; j<n; j++ )
{
scanf("%d",&a[j]);
}
__int64 sum = a[0];
l[0] = a[0];
for( j=1; j<n; j++ )
{
if( sum < 0 )
{
l[j] = a[j];
sum = l[j];
}
else
{
l[j] = sum + a[j];
sum = l[j];
}
}
sum = -INT_MAX;
for( j=0; j<n; j++ )
{
l[j] = max( sum, l[j] );
sum = l[j];
}
r[n-1] = a[n-1];
sum = a[n-1];
for( j=n-2; j>=0; j-- )
{
if( sum < 0 )
{
r[j] = a[j];
sum = r[j];
}
else
{
r[j] = sum + a[j];
sum = r[j];
}
}
sum = -INT_MAX;
for( j=n-1; j>=0; j-- )
{
r[j] = max( sum, r[j] );
sum = r[j];
}
sum = -INT_MAX;
for( j=0; j<n-1; j++ )
{
sum = max( sum, l[j]+r[j+1] );
}
printf( "%I64d/n", sum );
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: