您的位置:首页 > 其它

POJ 2479的简单想法

2014-07-28 22:09 204 查看
这道题是简单的dp例题拓展,问题是:给定一行数字,然后求这行数字中两个连续子序列和的最大值,并输出(两个子序列不能有重叠的部分);

由于是初学者,可能想法比较局限。我的总体思路是这样:这题肯定和最大求子序列有关,然后进行工作:用dp1[i]表示以第i个数结尾的最大子序列的和,用dp[i]表示已第i个数为起点的最大子序列的和;这样对于两个子序列和的最大值,把n分成2部分,[0-j],(j,n)在这两部分分别求dp1[i]得最大值和dp2[i]的最大值。这样的话,所取到的两个子序列一定不会有重合部分;

如何dp1[i],dp2[i]的最大值都[0,j],(j,n)这样的区间算的话,时间复杂度就是o(n^2),这样,我提交了试了一下,结果是tlo;然后我优化了一下:用数组max1[i]表示前i个数中dp1[j]的最大值,max2[i]表示后(i,n)中dp2[j]的最大值;

这样时间复杂度变为o(n),是不会超时的。下面是代码:

#include<cstdio>

#include<cstring>

using namespace std;

int a[60000];

int dp1[60000],dp2[60000],max1[60000],max2[60000];

int main()

{

freopen("test.txt","r",stdin);

int T;

scanf("%d",&T);

for(int i=0;i<T;i++)

{

int n;

scanf("%d",&n);

for(int j=0;j<n;j++)

{

scanf("%d",&a[j]);

}

dp1[0]=a[0];

for(int j=1;j<n;j++)

{

if(dp1[j-1]>0)

{

dp1[j]=dp1[j-1]+a[j];

}

else dp1[j]=a[j];

}

dp2[n-1]=a[n-1];

for(int j=n-2;j>=0;j--)

{

if(dp2[j+1]>0)

{

dp2[j]=dp2[j+1]+a[j];

}

else dp2[j]=a[j];

}

max1[0]=dp1[0];

for(int j=1;j<n;j++)

{

max1[j]=(max1[j-1]>dp1[j]?max1[j-1]:dp1[j]);

}

max2[n-1]=dp2[n-1];

for(int j=n-2;j>=0;j--)

{

max2[j]=(max2[j+1]>dp2[j]?max2[j+1]:dp2[j]);

}

int max=-400000;

for(int j=1;j<n;j++)

{

if(max<(max1[j-1]+max2[j]))

max=max1[j-1]+max2[j];

}

printf("%d\n",max);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: