hdu1003求最大子序列

来源:互联网 发布:定量和定性数据 编辑:程序博客网 时间:2024/05/16 05:33

分析:定义数组present[MAX]代表前i个数且包括第i个数的子序列的最大和,prior[MAX]表示前i个数最大子序列的和

所以有:present[i]=max(present[i-1]+s[i],s[i]);//前i-1个数包括第i-1个数的子序列最大和加上当前这个数构成的子序列,或者以当前这个数自成一个子序列,两者中选最大的。

                prior[i]=max(present[i],prior[i-1]);//前i个数的最大子序列和为:前i-1个数的最大子序列和或者前i个数且包括第i个数的最大子序列和。

继续分析发现每次求前i个最大子序列和都用不到0.....i-2的值,所以可以用滚动数组的思想节省内存

也就是:present=max(present+s[i],s[i]),prior=max(present,prior);每次计算前i个数时,present,prior就已经是前i-1的最大值,所以不需要present[i-1],prior[i-1];

对于输入的数s[i]也是每次都只需要用到s[i],对于s[0....i-1]不需要用到,所以在输入的时候计算就不需要用到s数组了。

此题还要记录选的子序列的第一个和最后一个,所以加个first,last辅助变量。

最终代码如下:


#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<iomanip>#define INF 99999999using namespace std;const int MAX=100001;int present,prior,s,first,last,temp;int main(){int t,n,num=1;cin>>t;while(t--){cin>>n;     present=prior=-INF;for(int i=1;i<=n;++i){cin>>s;present+=s;if(s>present){present=s;temp=i;}//present=max(present+s,s)if(present>prior){prior=present;first=temp;last=i;}//prior=max(prior,present);}cout<<"Case "<<num++<<":\n";cout<<prior<<" "<<first<<" "<<last<<endl;if(t)cout<<endl;}return 0;}


本题加强题:http://acm.hdu.edu.cn/showproblem.php?pid=1024

原创粉丝点击