Maximum Subsequence Sum

题目来源:点击打开链接

部分图片来源:点击打开链接

-------------------------------------------------------------------------------------------------------

算法1:穷举法

#include<iostream>

using namespace std;

long long MaxSubseqSum1(long long seq[], long long N);

int main()
{
	long long N;
	long long *p;

	cin>>N;
	p=new long long[N];

	for(long long i=0; i<N; i++)
	{
		cin>>p[i];
	}
	MaxSubseqSum1(p, N);

	delete []p;

	return 0;
}

long long MaxSubseqSum1(long long seq[], long long N)
{
	long long maxSum=seq[0];//记录子列和中的最大值
	long long thisSum=0;//记录某一子列的和
	long long m=0,n=0;
	for(long long i=0; i<N; i++)//子列的起始位置 i
	{
		for(long long j=i; j<N; j++)//子列的结束位置 j
		{
			thisSum=0;
			for(long long k=i; k<=j; k++)//计算所选子列的和
			{
				thisSum+=seq[k];
			}
			if(thisSum > maxSum)
			{
				m=i;//记录更新时,子列和对应的起始位置
				n=j;//记录更新时,子列和对应的终止位置
				maxSum=thisSum;
			}
		}
	}
	if(maxSum>=0)
	{
		cout<<maxSum<<" "<<seq[m]<<" "<<seq[n];
	}
	else
	{
		cout<<0<<" "<<seq[0]<<" "<<seq[N-1];
	}
	return maxSum;
}

 

算法2:穷举法(减少部分重复运算)

 

#include<iostream>

using namespace std;

long long MaxSubseqSum2(long long seq[], long long N);

int main()
{
	long long N;
	long long *p;

	cin>>N;
	p=new long long[N];

	for(long long i=0; i<N; i++)
	{
		cin>>p[i];
	}
	MaxSubseqSum2(p, N);

	delete []p;

	return 0;
}

long long MaxSubseqSum2(long long seq[], long long N)
{
	long long maxSum=seq[0];//记录子列和中的最大值
	long long thisSum=0;//记录某一子列的和
	long long m=0,n=0;
	for(long long i=0; i<N; i++)//子列的起始位置 i
	{
		thisSum=0;
		for(long long j=i; j<N; j++)//子列的结束位置 j
		{
			thisSum+=seq[j];//计算所选子列的和
			if(thisSum > maxSum)
			{
				m=i;//记录更新时,子列和对应的起始位置
				n=j;//记录更新时,子列和对应的终止位置
				maxSum=thisSum;
			}
		}
	}
	if(maxSum>=0)
	{
		cout<<maxSum<<" "<<seq[m]<<" "<<seq[n]<<endl;
	}
	else
	{
		cout<<0<<" "<<seq[0]<<" "<<seq[N-1]<<endl;
	}

	return maxSum;
}

 

算法3:在线方法

 

#include<iostream>

using namespace std;

long long MaxSubseqSum3(long long seq[], long long N);

int main()
{
	long long N;
	long long *p;

	cin>>N;
	p=new long long[N];

	for(long long i=0; i<N; i++)
	{
		cin>>p[i];
	}
	MaxSubseqSum3(p, N);

	delete []p;

	return 0;
}

long long MaxSubseqSum3(long long seq[], long long N)
{
	long long tempSum=0; //临时记录子列和的变量
	long long maxSum=seq[0];//记录子列和的最大值
	long long m=0,   /*记录起始位置*/
	          n=0,   /*记录终止位置*/
	          tag=-1;/*记录清零位置*/
	tempSum=0;
	for(int i=0; i<N; i++)
	{
		tempSum+=seq[i];

		if(tempSum>maxSum)//发现更大子列和则更新maxSum
		{
			maxSum=tempSum;
			n=i;
			m=tag+1;
		}
		else
		{
			if(tempSum<0)
			{
				tempSum=0;
				tag=i;
			}
		}
	}

	if(maxSum>=0)
	{
		cout<<maxSum<<" "<<seq[m]<<" "<<seq[n];
	}
	else
	{
		cout<<0<<" "<<seq[0]<<" "<<seq[N-1];
	}
	return maxSum;
}

 

算法4:“分而治之”(递归实现)

 

#include<iostream>

using namespace std;

class newType
{
	public:
		long long data;//记录数据
		long long index1;//记录首位值
		long long index2;//记录末位置
		void operator=(newType a)
		{
			this->data=a.data;
			this->index1=a.index1;
			this->index2=a.index2;
		}
};

newType Max3( newType v1, newType v2, newType v3);
newType _MaxSubseqSum4(long long seq[], long long start, long long end);
newType MaxSubseqSum4(long long seq[], long long N);


int main()
{
	long long N;
	long long *p;

	cin>>N;
	p=new long long[N];

	for(long long i=0; i<N; i++)
	{
		cin>>p[i];
	}

	newType temp;
	temp=MaxSubseqSum4(p, N);
	cout<<temp.data<<" "<<p[temp.index1]<<" "<<p[temp.index2]<<endl;

	delete []p;

	return 0;
}

newType Max3( newType v1, newType v2, newType v3)
{
	newType temp;
	if(v1.data>=v2.data & v1.data>=v3.data)
	{
		return v1;
	}
	if(v2.data>=v3.data & v2.data>=v1.data)
	{
		return v2;
	}
	if(v3.data>=v1.data & v3.data>=v2.data)
	{
		return v3;
	}

}

newType _MaxSubseqSum4(long long seq[], long long start, long long end)
{
	//判断递归是否要结束
	if(start==end) //只有一个数字时
	{
		newType temp;
		temp.data=seq[start];
		temp.index1=start;
		temp.index2=end;
		return temp;
	}

	newType maxSubseqSum_left,     /*记录从start到mid范围内的最大子列和 */
	        maxSubseqSum_right,    /*记录从mid+1到end范围内的最大子列和 */
	        maxSum_left,           /*记录以mid为起点向左扫描到start过程中,累加得到的最大和 */
	        maxSum_right,          /*记录以mid+1为起点向右扫描到end过程中,累加得到的最大和 */
	        maxSubseqSum_cross_mid;/*记录从start到end的范围内,所有包含mid项的子列和的最大值 */
	long long mid=0;
	mid=(start+end)/2;//得到分割位置
	maxSubseqSum_left=_MaxSubseqSum4(seq, start, mid);	//计算左边的最大子列和
	maxSubseqSum_right=_MaxSubseqSum4(seq, mid+1, end);	//计算右边的最大子列和
	//计算跨越中间线的最大子列和//
	//往左扫描,得到左边最大和
	long long tempSum=0;//临时存储变量
	maxSum_left.data=seq[mid];
	maxSum_left.index1=mid;
	maxSum_left.index2=mid;
	for(int i=mid; i>=start; i--) /*以mid为起点向左扫描到start过程中,累加得到的最大和 */
	{
		tempSum+=seq[i];
		if(tempSum>=maxSum_left.data)
		{
			maxSum_left.data=tempSum;
			maxSum_left.index1=i;
		}
	}
	//往右边扫描,得到右边最大和
	tempSum=0;
	maxSum_right.data=seq[mid+1];
	maxSum_right.index1=mid+1;
	maxSum_right.index2=mid+1;
	for(int i=mid+1; i<=end; i++)/*以mid+1为起点向右扫描到end过程中,累加得到的最大和 */
	{
		tempSum+=seq[i];
		if(tempSum>maxSum_right.data)
		{
			maxSum_right.data=tempSum;
			maxSum_right.index2=i;
		}
	}
	maxSubseqSum_cross_mid.data=maxSum_left.data+maxSum_right.data;
	maxSubseqSum_cross_mid.index1=maxSum_left.index1;
	maxSubseqSum_cross_mid.index2=maxSum_right.index2;
	//得到整个序列的最大子列和
	return Max3(maxSubseqSum_left, maxSubseqSum_cross_mid, maxSubseqSum_right);
}

newType MaxSubseqSum4(long long seq[], long long N)
{
	newType temp;
	temp=_MaxSubseqSum4(seq, 0, N-1);
	if(temp.data<0)
	{
		temp.data=0;
		temp.index1=0;
		temp.index2=N-1;
	}
	return temp;
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值