返回顶部

Max Sum

Vjudge

  • Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.

  • Input
    The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).

  • Output
    For each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.

  • Sample

  • Input

    2								
    5 6 -1 5 4 -7					
    7 0 6 -1 1 -6 7 -5 				
    
  • Output

    Case 1:
    14 1 4
    
    Case 2:
    7 1 6
    

    原思路:直接DP,用一维数组,否则会爆,但还是会超时
    超时代码如下

    点击查看代码
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <math.h>
    #include <string.h>
    using namespace std;
    int t,n,a[100005],dp[100005],k;
    void solve()
    {
    	cin>>n;
    	memset(a,0,sizeof(a));
    	memset(dp,0,sizeof(dp));
    //	memset(vis,0,sizeof(vis));
    	for(int i=1;i<=n;i++)
    	{
    		cin>>a[i];
    	}
    	int ans=0,st=0,en=0;
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=i;j<=n;j++)
    		{
    			if(dp[j]<dp[j-1]+a[j])
    			{
    				dp[j]=dp[j-1]+a[j];
    			}
    			//dp[j]=max(dp[j],dp[j-1]+a[j]);
    			if(ans<dp[j])
    			{
    				ans=dp[j];
    				st=i,en=j;
    			}
    
    //			cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
    		}
    	}
    	cout<<"Case "<<k<<":"<<endl;
    	cout<<ans<<" "<<st<<" "<<en<<endl;
    	if(t)cout<<endl;
    }
    int main()
    {
    	ios_base::sync_with_stdio(false);
    	cin.tie(0);cout.tie(0);
    	cin>>t;
    	while(t--)
    	{
    		k++;
    		solve();
    	}
    	return 0;
    }
    

    O(n^2)的复杂度显然会超时,所以我们可以用前缀和维护,代替数组

    • 注意事项:记录最大的开始的变量需要与此时正在进行的情况的起点变量区分开,
      否则就Wa了
    点击查看代码
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <math.h>
    #include <string.h>
    using namespace std;
    int t,n,a[100005],k;
    void solve()
    {
    	cin>>n;
    	memset(a,0,sizeof(a));
    //	memset(vis,0,sizeof(vis));
    	for(int i=1;i<=n;i++)
    	{
    		cin>>a[i];
    	}
    	int ans=-9999999,st=1,en=1,sum=0,head=1;
    	for(int i=1;i<=n;i++)
    	{
    		sum=sum+a[i];
    		if(sum>ans)
    		{
    			ans=sum;
    			st=head;
    			en=i;
    		}
    		if(sum<0)
    		{
    			sum=0;
    			head=i+1;
    		}
    	}
    	cout<<"Case "<<k<<":"<<endl;
    	cout<<ans<<" "<<st<<" "<<en<<endl;
    	if(t)cout<<endl;
    }
    int main()
    {
    	ios_base::sync_with_stdio(false);
    	cin.tie(0);cout.tie(0);
    	cin>>t;
    	while(t--)
    	{
    		k++;
    		solve();
    	}
    	return 0;
    }
    
posted @ 2024-02-20 11:25  wlesq  阅读(6)  评论(0编辑  收藏  举报