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