C语言(最大子数组问题)

最大子数组问题

已知一支股票每天的价格,要获得最大收益,就要在股票价格尽量低时买入,价格尽量高时卖出,同时卖出时间再买入事件之后。要求出这个最大收益,可以建立一个每天价格和前一天价格差的数组,然后求出最大子数组(如果价格递增,最大子数组是整个数组)数据之和。

#include<stdio.h>
#define N 20
int DivideMatrix(int a[],int n,int former,int latter);
int MidMax(int a[],int mid,int n,int former,int latter);
int main(void)
{
    int a[N]={0},b[N]={0},n=0,i=0,flag=0,max=0,former=0,latter=0;
    printf("请输入调查天数(<=20)\n");
    scanf("%d",&n);
    printf("请输入股票价格\n");
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(i=1;i<n;i++)
    {
        b[i-1]=a[i]-a[i-1];
        if(b[i-1]<0)
        {
            flag=1;
        }
    }
    n=n-1;
    latter=n-1;
    if(flag==0)
    {
        for(i=0;i<n;i++)
        {
            max+=b[i];
        }
    }
    else
    {
        max=DivideMatrix(b,n,former,latter);
    }
    printf("最大收益是%d\n",max);
}
int DivideMatrix(int a[],int n,int former,int latter)
{
    int mid=0,max1=0,max2=0,max3=0;
    if(former<latter)
    {
    	mid=(former+latter)/2;
		max1=DivideMatrix(a,n,former,mid);
		max2=DivideMatrix(a,n,mid+1,latter);
		max3=MidMax(a,mid,n,former,latter);
		if(max1>max2&&max1>max3)
		{
			return max1;
		}
		else if(max2>max1&&max2>max3)
		{
			return max2;
		}
		else
		{
			return max3;
		}
	}
	return a[former];	
}
int MidMax(int a[],int mid,int n,int former,int latter)
{
	int lmax=0,rmax=0,i=0,b=0,c=0;
    lmax=a[mid];
    rmax=a[mid+1];
	for(i=mid;i>=former;i--)
	{
		b+=a[i];
		if(b>lmax)
		{
			lmax=b;
		}
	}
	for(i=mid+1;i<=latter;i++)
	{
		c+=a[i];
		if(c>rmax)
		{
			rmax=c;
		}
	}
	return lmax+rmax;
}

比如,17天中股票价格分别为100 113 110 85 105 102 86 63 81 101 94 106 101 79 94 90 97,它的价格差数组为13 -3 -25 20 -3 -16 -23 18 20 -7 12 -5 -22 15 -4 7,最大子数组为18 20 -7 12,和为43,即为所求。

第二种思想,从数组左边开始,依次寻找最大子数组之和。若已知A[1...j ]的最大子数组,A[1...j+1]的最大子数组要么是A[1...j]的最大子数组,要么是A[i...j+1]的最大子数组(1<=i<=j+1)。

#include<stdio.h>
#define N 20
int FindMax(int a[],int latter);
int main(void)
{
    int a[N]={0},b[N]={0},n=0,i=0,flag=0,max=0;
    printf("请输入调查天数(<=20)\n");
    scanf("%d",&n);
    printf("请输入股票价格\n");
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(i=1;i<n;i++)
    {
        b[i-1]=a[i]-a[i-1];
        if(b[i-1]<0)
        {
            flag=1;
        }
    }
    n=n-1;
    if(flag==0)
    {
        for(i=0;i<n;i++)
        {
            max+=b[i];
        }
    }
    else
    {
        max=FindMax(b,n);
    }
    printf("最大收益是%d\n",max);
}
int FindMax(int a[],int latter)
{
    if(latter==0)
    {
        return a[0];
    }
    int max=0,i=0,k=0;
    max=FindMax(a,latter-1);
    for(i=latter;i>=0;i--)
    {
        k+=a[i];
        if(k>max)
        {
            max=k;
        }
    }
    return max;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值