HDU 1003 Max Sum

 (1)最基础的方法。O(n^2)

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>

int main()
{
	int k=1,T;
	scanf("%d",&T);
	while(k<=T)
	{
		int N;
		scanf("%d",&N);
		int *data=(int *)malloc(sizeof(int)*N);	
		for(int i=0;i<N;i++)
			scanf("%d",&data[i]);
		int Max=INT_MIN,sum=0;
		int left,right;
		for(int i=0;i<N;i++)
		{
			sum=0;
			for(int j=i;j<N;j++)
			{
				sum+=data[j];
				if(sum>Max)
				{
					Max=sum;
					left=i;
					right=j;
				}		
			}
		}
		
		printf("Case %d:\n",k);
		printf("%d %d %d\n",Max,left+1,right+1);
		if(k!=T) printf("\n");
		free(data);
		k++;	
	}
	return 0;	
} 

(2)分治

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>

typedef struct Node
{
	int Sum;
	int l_index;
	int r_index;	
}Node;
Node solve_mid(int *data,int low,int high)
{
	Node Max;
	int l_sum=INT_MIN,r_sum=INT_MIN,mid=(low+high)/2,sum=0;
	for(int i=mid;i>=low;i--)
	{
		sum+=data[i];
		if(sum>=l_sum)//这里应该是 >=,因为是向左寻找,并且题目要求输出 第一个 满足要求的结果 
		{
			l_sum=sum;
			Max.l_index=i;
		}
	}
	sum=0;
	for(int i=mid+1;i<=high;i++)
	{
		sum+=data[i];
		if(sum>r_sum)
		{
			r_sum=sum;
			Max.r_index=i;
		}
	}
	Max.Sum=l_sum+r_sum;
	return Max;	
}
Node solve(int *data,int low,int high)
{
	if(low==high) {//这个地方需不需要返回下标的值? 
		Node Max;
		Max.Sum=data[low];
		Max.l_index=low;
		Max.r_index=high;
		return Max;
	}
	
	int mid=(low+high)/2;
	Node ret1=solve(data,low,mid);
	Node ret2=solve_mid(data,low,high);
	Node ret3=solve(data,mid+1,high);
	
	Node Max;
	if(ret1.Sum>=ret2.Sum) Max=ret1;
	else Max=ret2;
	if(Max.Sum<ret3.Sum) Max=ret3;
	return Max;
}

这里下标值的返回也可以采用引用

(3)线性

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>

int main() 
{
	int k=1,T;
	scanf("%d",&T);
	while(k<=T)
	{
		long N;
		scanf("%d",&N);
		int data[100001];	
		for(long i=0;i<N;i++)
			scanf("%d",&data[i]);
		
		long Max=INT_MIN,left,right,temp=0; 
		long sum=0;
		for(long i=0;i<N;i++)
		{
			sum+=data[i];
			if(sum>Max)
			{
				Max=sum;
				left=temp;//假设最大子序列从下标为 0 的元素开始 
				right=i;//实时更新最大子序列的 最大右下标值 
			}
//一个子序列必然是以正数开头的,因为如果以负数开头,那么去掉这个子序列,那得到一个更优解			
			if(sum<0)
			{
				sum=0;
				temp=i+1;//啦啦 
			}	
		}
		
		printf("Case %d:\n",k);
		printf("%ld %ld %ld\n",Max,left+1,right+1);
		if(k!=T) printf("\n");
		k++;	
	}
	return 0;	
} 

思路三参考代码来源:https://blog.youkuaiyun.com/wptad/article/details/1709598

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值