hdu1003 最大子序列的和

来源:互联网 发布:知乎 订阅 编辑:程序博客网 时间:2024/04/29 23:15

题目大意:给出一串数字,求出子序列中的最大和。

思路:典型的dp问题,状态转移方程为:dp[i]=max{dp[i-1],dp[i-1]+a[i]}.设置start和end两个指标,用来记录结果子序列中的开始和结束的位置。

值得注意的是这道题目中的格式要求很多,一开始没太在意所以wrong answer 了好几次。

如下是第一次AC的代码:

# include <iostream># include <algorithm>using namespace std;int a[100005],dp[100005];int main (){int total,t;int n,i,k,maxs,start,end;scanf("%d",&total);t=total;while(t--){memset(a,0,sizeof(a));memset(dp,0,sizeof(dp));scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d",&a[i]);}dp[1]=a[1];maxs=dp[1];k=start=end=1;for(i=2;i<=n;i++){if((dp[i-1]+a[i])<a[i]){dp[i]=a[i];k=i;}elsedp[i]=dp[i-1]+a[i];if(dp[i]>maxs){maxs=dp[i];start=k;end=i;}}printf("%s%d:\n%d %d %d\n","Case ",total-t,maxs,start,end);if(t)printf("\n");}//system("pause");return 0;}

之后尝试了下改进,代码如下。因为从上面的循环中可以看出,其实两个数组并没有什么用,完全可以用一个变量来替代,这样就需要在读入数据的同时做处理,边度数据,边累加处理。

# include <iostream># include <algorithm>using namespace std;int main (){int total,t;int n,i,k,maxs,start,end,sum,a;scanf("%d",&total);t=total;while(t--){scanf("%d",&n);scanf("%d",&a);start=end=k=1;maxs=sum=a;for(i=2;i<=n;i++){scanf("%d",&a);sum=sum+a;if(sum<a){    sum=a;k=i;}if(maxs<sum){maxs=sum;start=k;end=i;}}printf("%s%d:\n%d %d %d\n","Case ",total-t,maxs,start,end);if(t)printf("\n");}system("pause");return 0;}


0 0