Description
Input
Output
Sample Input
2 5 6 -1 5 4 -7 7 0 6 -1 1 -6 7 -5
Sample Output
Case 1: 14 1 4 Case 2: 7 1 6
题目大意:求所给序列的最大子序列之和,并求出该最大子序列的首位和末位的位置。
分析:开一个dp数组记录以每位数字结尾的最大子序列之和,比较求出最大的子序列之和,并记录该子序列结尾的
数字序号,从结尾数字向前累加,直到和等于求得的最大子序列之和,记录此时的数字序号,便是该最大子
序列的首位。
注意:1,在第二个样例中,0作为最大子序列的首位。
2,当最大子序列为一个数字时,首位与末位相同。
3,最后一组结果后不需要空行。
代码如下:
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<cstdio>
using namespace std;
int a[100005],dp[100005];
int main()
{
int i,j,k,n,t,mm,nn,st,en,sum;
scanf("%d",&t);
for(i=0;i<t;i++)
{
sum=0;
memset(dp,0,sizeof(dp));
scanf("%d",&n);
for(j=1;j<=n;j++)
scanf("%d",&a[j]);
dp[1]=a[1];
for(j=2;j<=n;j++)
{
if(a[j]+dp[j-1]>a[j])
dp[j]=a[j]+dp[j-1];
else
dp[j]=a[j];
}
mm=dp[1];
nn=1;
for(j=2;j<=n;j++)
{
if(dp[j]>mm)
{mm=dp[j];nn=j;}
}
if(mm==a[nn]&&(dp[nn-1]!=0||nn-1<1))
{st=nn;en=nn;}
else
{
en=nn;
sum=a[nn];
for(j=nn-1;j>=1;j--)
{
sum+=a[j];
if(sum==mm)
{
if(a[j-1]==0&&j-1>=1)
st=j-1;
else
st=j;
break;
}
}
}
printf("Case %d:\n",i+1);
printf("%d %d %d\n",mm,st,en);
if(t-i>1)
printf("\n");
}
getchar();
getchar();
return 0;
}
ps:第一次写博客,有错误望大家指出