问题:输入一个整形数组,有正数、负数或者零。数组中连续的一段序列成为其子序列。求出所有子序列中元素和最大的子序列,写出路径和元素和。
代码参考如下:
/**
*
*By Eric
**/
#include <stdlib.h>
#include <iostream>
using namespace std;
#define MAX 100
int main()
{
int N; //数据数目
int Data[MAX]; //储存数据的数组
int Data2[MAX]; //存储路径
int length = 0;
cin>>N; //输入数据数目
for(int i=0;i<N;i++)cin>>Data[i]; //输入数据
int g = 0;
while(Data[g] <= 0)g++;
int max = Data[g]; //max初始化为数据中的第一个正数
for(int i=g;i<N;i++)
{
int tmp =0;
for(int j=i;j<N;j++)
{
tmp += Data[j];
if(max < tmp)
{
max = tmp;
length = j-i+1;
for(int k=i;k<=j;k++)Data2[k-i] = Data[k];
}
}
}
cout<<"path: ";
for(int i=0;i<length;i++)cout<<Data2[i]<<" ";
cout<<endl<<"max: ";
cout<<max;
system("pause");
}
以上为交简单的枚举法,通过优化算法,可以考虑采用分治归并以及递归的思路来解决问题。
代码如下:
/**
*最大子序列 分治归并法
*By Eric 2011.11.14
**/
#include <stdlib.h>
#include <iostream>
#define MAX 100
using namespace std;
int ThreeMax(int a,int b,int c)
{
if(a>=b&&a>=c)return a;
if(b>=a&&b>=c)return b;
if(c>=a&&c>=b)return c;
}
int FindMax(int Data[],int left,int right)
{
int center = (left+right)/2;
int MaxLeft = 0,LeftSum = 0;
int MaxRight = 0,RightSum = 0;
if(left == right)
if(Data[left]>0)return Data[left];
else
return 0;
for(int i=center;i>=left;i--)
{
LeftSum += Data[i];
if(MaxLeft<LeftSum)MaxLeft = LeftSum;
}
for(int i=center+1;i<=right;i++)
{
RightSum += Data[i];
if(MaxRight<RightSum)MaxRight = RightSum;
}
return ThreeMax(FindMax(Data,left,center),FindMax(Data,center+1,right),MaxLeft+MaxRight);
}
int main()
{
int N; //数组长度
int Data[MAX];
cin>>N;
for(int i=0;i<N;i++)Data[i]=rand()%9-5; //产生随机数
for(int i=0;i<N;i++)cout<<Data[i]<<" ";
cout<<endl<<FindMax(Data,0,N-1);
system("pause");
}
简单遍历,代码如下:
/**
*最小子序列
*By Eric 2011.11.14
**/
#include <stdlib.h>
#include <iostream>
#define MAX 100
using namespace std;
int main()
{
int N;
cin>>N;
int Data[MAX];
for(int i=0;i<N;i++)Data[i] = rand()%9-5;
for(int i=0;i<N;i++)cout<<Data[i]<<" ";
int ThisSum = 0;
int MaxSum =0;
for(int i=0;i<N;i++)
{
ThisSum += Data[i];
if(ThisSum > MaxSum)MaxSum = ThisSum;
else if(ThisSum<0)ThisSum=0;
}
cout<<endl<<MaxSum;
system("pause");
}