POJ 2593解题报告
题目来源 :PKU 2593
http://acm.pku.edu.cn/JudgeOnline/problem?id=2593
解法类型 :动态规划应用
作 者 :刘亚宁
题目大意:
抽取一个整数序列的两个子序列,求所有抽取方法中得到两个序列和的最大值。
题目思路:
用两个数组数组记录从前和从后子序列加和的最大值,每个元素的值为从前(后)加和至该位置得到的最大值。
遍历数组每个位置,找出所有位置为分界点的最大值即为结果。
其中得到子序列最大和过程比较特殊,详见代码。
提交情况:
Run time error(以后简称rte)一次:数组不够大,省题没注意数据范围。
Time Limit Exceeded(以后简称tle)一次:没有应用前和后的数组进行数据的存储。
注意:
两个子序列和的最大值 不是最大子序列和 与 第二大不想交子序列和 的sum(错因:例如数据3、 3、 -3、 4、 -2、 1)
源程序:
#include <iostream>
#define MIN -2000000000
using namespace std;
long a[110000],front[110000],back[110000];
int main()
{
long num,i,r,k;
while(cin>>num,num)
{
for(i=1;i<=num;i++) cin>>a[i];
front[0]=MIN;//特殊处理边界情况
back[num+1]=MIN;
for(i=1;i<=num;i++)
{
k=(front[i-1]+a[i])>a[i]?(front[i-1]+a[i]):a[i];
front[i]=front[i-1]>k?front[i-1]:k;//从前向后,找到加上a对应位置的值、不加该值、和只有该值(可能是一序列的开头)的最大者,记录于front数组
}
for(i=num;i>=1;i--)
{
k=(back[i+1]+a[i])>a[i]?(back[i+1]+a[i]):a[i];
back[i]=back[i+1]>k?back[i+1]:k;
}//从后向前,进行类似的活动
r=MIN;
for(i=1;i<num;i++)
if(front[i]+back[i+1]>r) r=front[i]+back[i+1];//从 所有前后两个序列的分界位置 所对应的和中 找到最大的 即为结果
cout<<r<<endl;
}
return 0;
}
posted on 2010-03-05 10:12 liugoodness 阅读(484) 评论(0) 编辑 收藏 举报