最大子數組問題暴力求解算法複雜度2^n
兩種高效方法求最大字數組問題
問題:求一個數組中相加可以獲得最大值的子數組,子數組是指原數組中任意連續的一段、
1.遞歸與分治法 (複雜度nlogn)
代碼:
#include <iostream>
using namespace std;
int max_mid(int *a,int mid,int low,int high)
{
int ml = a[mid];
int mr = 0;
int sum = ml;
for(int i = mid-1; i>=low; i--)
{
sum = sum+a[i];
if(sum>ml)
{
ml = sum;
}
}
sum = 0;
for(int i = mid+1; i<=high; i++)
{
sum = sum+a[i];
if(sum>mr)
{
mr = sum;
}
}
return ml+mr;
}
int max(int *a,int low,int high)
{
if(low == high)
{
return a[low];
}
else
{
int mm;
int ml;
int mr;
int mid = (low+high)/2;
ml = max(a,low,mid);
mm = max_mid(a,mid,low,high);
mr = max(a,mid+1,high);
if(mm>=ml&&mm>=mr)
{
return mm;
}
if(ml>=mm&&ml>=mr)
{
return ml;
}
else
{
return mr;
}
}
}
int a[1000];
int main()
{
int n;
while(cin>>n)
{
for(int i = 0; i<n; i++)
{
cin>>a[i];
}
cout<<max(a,0,n-1)<<endl;
}
return 0;
}
2.動態規劃法(算法複雜度n):
</pre><p><pre class="cpp" name="code">#include<iostream>
using namespace std;
int a[1000];
int max(int *a,int n)
{
int sum = a[0],b = a[0];
for(int i = 1;i<n;i++)
{
// b用來計算i之前包括i的子段的最大值
if(b>0)
{
b+=a[i];
}
else
{
b = a[i];
}
// 因爲最大子段和包括在循環的某個b中所以記錄最大的b值
if(b>sum)
{
sum = b;
}
}
return sum;
}
int main()
{
int n;
while(cin>>n)
{
for(int i = 0;i<n;i++)
{
cin>>a[i];
}
cout<<max(a,n)<<endl;
}
}