问题:给定整数A1,A2,.... (可能有负数),求最大的连续子序列
第一种方法:
暴力求解
int Sum1(const int a[],int n)
{
int maxSum = a[0];
for(int i = 0;i < n ;i++)
for(int j = i;j < n;j++)
{
int temSum = 0;
for(int k = i;k <= j;k++)
temSum += a[k];
if(temSum > maxSum)maxSum = temSum;
}
return maxSum;
}
第二种
暴力求解略微改进
int Sum2(const int a[], int n)
{
int maxSum = a[0];
for(int i = 0;i < n;i++)
{
int tem = 0;
for(int j = i;j < n;j++)
{
tem += a[j];
if(tem > maxSum)maxSum = tem;
}
}
return maxSum;
}
第三种
分治方法
int Sum3Tem(const int a[],int left,int right)
{
int MaxLeftSum,MaxRightSum;
int MaxLeftBorderSum,MaxRightBorderSum;
int LeftBorder,rightBorder;
int center;
if(left == right)
{
if(a[left])return a[left];
else return 0;
}
center = (left + right) / 2;
MaxLeftSum = Sum3Tem(a,left,center);
MaxRightSum = Sum3Tem(a,center + 1,right);
LeftBorder = 0;MaxLeftBorderSum = 0;
for(int i = center; i >= left; i--)
{
LeftBorder += a[i];
if(LeftBorder > MaxLeftBorderSum)MaxLeftBorderSum = LeftBorder;
}
rightBorder = 0;MaxRightBorderSum = 0;
for(int i = center + 1;i <= right;i++)
{
rightBorder += a[i];
if(rightBorder > MaxRightBorderSum)MaxRightBorderSum = rightBorder;
}
return max(max(MaxLeftSum,MaxRightSum),MaxRightBorderSum + MaxLeftBorderSum);
}
int Sum3(const int a[],int n)
{
return Sum3Tem(a,0,n-1);
}
动态规划
状态转移方程
dp[i] = max(dp[i-1] + a[i],a[i]);
可以看这篇文章
int Sum4(const int a[],int n)
{
int MaxSum = a[0];
int SumTem = 0;
for(int i = 0;i < n;i++)
{
SumTem += a[i];
if(SumTem > MaxSum)MaxSum = SumTem;
else if(SumTem < 0)SumTem = 0;
}
return MaxSum;
}
=======================
完整代码 测试数据总共有3000个 还在大了 要等太久 3000个可以看出差别了
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <fstream>
using namespace std;
// O(n 3)
int Sum1(const int a[],int n)
{
int maxSum = a[0];
for(int i = 0;i < n ;i++)
for(int j = i;j < n;j++)
{
int temSum = 0;
for(int k = i;k <= j;k++)
temSum += a[k];
if(temSum > maxSum)maxSum = temSum;
}
return maxSum;
}
//O (n 2)
int Sum2(const int a[], int n)
{
int maxSum = a[0];
for(int i = 0;i < n;i++)
{
int tem = 0;
for(int j = i;j < n;j++)
{
tem += a[j];
if(tem > maxSum)maxSum = tem;
}
}
return maxSum;
}
int Sum3Tem(const int a[],int left,int right)
{
int MaxLeftSum,MaxRightSum;
int MaxLeftBorderSum,MaxRightBorderSum;
int LeftBorder,rightBorder;
int center;
if(left == right)
{
if(a[left])return a[left];
else return 0;
}
center = (left + right) / 2;
MaxLeftSum = Sum3Tem(a,left,center);
MaxRightSum = Sum3Tem(a,center + 1,right);
LeftBorder = 0;MaxLeftBorderSum = 0;
for(int i = center; i >= left; i--)
{
LeftBorder += a[i];
if(LeftBorder > MaxLeftBorderSum)MaxLeftBorderSum = LeftBorder;
}
rightBorder = 0;MaxRightBorderSum = 0;
for(int i = center + 1;i <= right;i++)
{
rightBorder += a[i];
if(rightBorder > MaxRightBorderSum)MaxRightBorderSum = rightBorder;
}
return max(max(MaxLeftSum,MaxRightSum),MaxRightBorderSum + MaxLeftBorderSum);
}
int Sum3(const int a[],int n)
{
return Sum3Tem(a,0,n-1);
}
int Sum4(const int a[],int n)
{
int MaxSum = a[0];
int SumTem = 0;
for(int i = 0;i < n;i++)
{
SumTem += a[i];
if(SumTem > MaxSum)MaxSum = SumTem;
else if(SumTem < 0)SumTem = 0;
}
return MaxSum;
}
int main()
{
const int num = 3000;
//int a[6] = {-2,11,-4,13,-5,-2};
int b[num];
clock_t start,finish;
freopen("randNum.txt","r",stdin);
for(int i = 0;i < num;i++)
cin>>b[i];
start = clock();
cout<<"sum1: "<<Sum1(b,num);
finish = clock();
cout<<" cost "<<double(finish - start) / CLOCKS_PER_SEC<<endl;
start = clock();
cout<<"sum2: "<<Sum2(b,num);
finish = clock();
cout<<" cost "<<double(finish - start) / CLOCKS_PER_SEC<<endl;
start = clock();
cout<<"sum3: "<<Sum3(b,num);
finish = clock();
cout<<" cost "<<double(finish - start) / CLOCKS_PER_SEC<<endl;
start = clock();
cout<<"sum4: "<<Sum4(b,num);
finish = clock();
cout<<" cost "<<double(finish - start) / CLOCKS_PER_SEC<<endl;
return 0;
}
=====================================
为了得到测试数据
先写了一个随机数生成的程序,随机生成1000个数,范围[-100,100)
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstdio>
using namespace std;
int main()
{
srand(time(NULL));
freopen("randNum.txt","w",stdout);
int totalNum = 1000;
while(totalNum--)
{
cout<<(rand() % 200 - 100)<<" ";
}
return 0;
}