杭电ACM 1003 :Max Sum

来源:互联网 发布:美国非农数据公布网址 编辑:程序博客网 时间:2024/04/28 16:50

题目源地址:http://acm.hdu.edu.cn/showproblem.php?pid=1003

         这是一个很经典的问题,这个题目我的大致思路是先用一个result数组存储到包含第i个数时的最大字段和,则result[i]的结果可以通过一个递推公式得到:result[i]=max{result[i-1]+a[j],a[j]},这个值表示包含第i个数最大字段和,如果result[i]的值小于0,则将result[i]的值置为当前值,这说明任何一个小于0的子序列都不可能是最大子序列的前缀。

           具体操作时可以一边输入一边记录这个最大的值以及所在的位置,数组输入完也就找到了最大的和以及子序列的最后一个元素的位置end。然后从end位置向前找,直到找到result[i]为零时停止,start位置就是i+1 。算法的时间复杂度为O(n),只要两次就可以就可以完成。

C++代码:

#include<stdio.h>int num[100001];int result[100001];int max(int a,int b){if(a>b)return a;else return b;}int main(){int T;scanf("%d",&T);for(int iCase=1;iCase<=T;iCase++){int n,max_v=-1001;int start=0,end=0;scanf("%d",&n);scanf("%d",&num[0]);max_v=result[0]=num[0];for(int i=1;i<n;i++){scanf("%d",&num[i]);result[i]=max(result[i-1]+num[i],num[i]);if(result[i]>max_v){max_v=result[i];end=i;}}for(int i=end-1;i>=0;i--){if(result[i]<0){start=i+1;break;}}printf("Case %d:\n",iCase);printf("%d %d %d\n",result[end],start+1,end+1);if(iCase!=T)printf("\n");}return 0;}
令附一个AC代码:

#include<iostream>using namespace std;int main(){int i,j,k=0,loop1,loop2,a,start,end,max,temp;cin>>loop1;for(i=0;i<loop1;i++){max=-1001,temp=start=k=0;cin>>loop2;for(j=0;j<loop2;j++){cin>>a;temp+=a;if(temp>max){start=k;end=j;max=temp;}if(temp<0){temp=0;k=j+1;}}cout<<"Case "<<i+1<<":"<<endl;cout<<max<<" "<<start+1<<" "<<end+1<<endl;if(i+1!=loop1)cout<<endl;}return 0;}



原创粉丝点击