问题重述:给定一个数列,寻找该数列的一个最大子列和,并返回该子列的首尾元素。例如:给定序列{ -2, 11, -4, 13, -5, -2 },最大子列为{ 11, -4, 13 } ,子列和为20。
输入描述:第一行为该序列的数据个数,第二行为该序列的具体元素。
输出要求:
1、第一行第一个位置输出最大子列和,第二个位置输出最大子列的第一个元素,第三个位置输出最大子列的最后一个元素;
2、如果最大子列和不唯一,输出下标比较小的子列元素;
3、如果序列的每个元素都小于0,则最大序列和输出为0,且返回整个序列的首尾元素。
Sample Input:
10
-10 1 2 3 4 -5 -23 3 7 -21
Sample Output:
10 1 4
实现代码:
#include<iostream>
using namespace std;
void MaxSubseqSum(int K,int a[])
{
int BAN[2];//BAN数组存放最大子列的首尾元素
int MaxSum = 0;//初值设为负值,方便处理序列含有负数和0的情况(-1 -2 0)
int ThisSum = 0;//定义每次加和
BAN[0]=a[0];
BAN[1]=a[0];
int tmp=0;//定义初始变量。存放可能出现最大子列第一个元素的位置
for (int i = 0; i < K; i++)
{
ThisSum+=a[i]; //在线处理
if(MaxSum<ThisSum)//最大值小于当前加和
{
BAN[0]=a[tmp];//更新为存放的下标对应元素
BAN[1]=a[i];//实时更新当前下标
MaxSum = ThisSum;//更新最大值
}
else if(ThisSum<0)//一旦当前序列和出现负值,就没有意义了,需要置0
{
ThisSum=0;
tmp=i+1;//下一个元素可能是最大值,记录下标
}
}
if(MaxSum>0)//找到了最大序列和
{
cout<<MaxSum<<" "<<BAN[0]<<" "<<BAN[1];
}
else//全为负值或者负值和0
{ int flag=0;//统计负数出现的次数
for(int i=0;i<K;i++)
{
if(a[i]<0)
{
flag++;
}
}
if(flag==K)
{
cout<<"0"<<" "<<a[0]<<" "<<a[K-1];//全是负值
}
else
{
cout<<MaxSum<<" "<<BAN[0]<<" "<<BAN[1];//有0有负值
}
}
}
int main()
{
int K;
cin >> K;
int a[100000];
for (int i = 0; i < K; i++)
{
cin >> a[i];
}
//寻找最大子列
MaxSubseqSum(K,a);
return 0;
}
超详细注释,看不懂你打我。。。
程序加了很多情况的判断,以通过多种输入类型测试。
觉着有帮助就点个赞吧,让我知道你的存在~