求乙個序列的最大子段和即最大連續子串行之和
2、列舉法
列舉變數:每一段的起點和終點
列舉範圍:起點:1- n,終點:起點-n;
判斷條件:找最大值即可
複雜度:o(nnn)
#include
using nampespace std;
int a[
20005];
intmain()
int maxx=
-0x7fffffff;
for(int i=
1;i<=n;i++)if
(sum>maxx)
maxx=sum;}}
} cout
}
3、優化(減少重複計算)
序列從i 到 j 的一段和可以表示為從頭到 j 的和減去從 從頭到 i 段的和,最後再加上 a[i];
s[i-j]=s[j]-s[i]+a[i]
複雜度:o(n*n)
#include
using nampespace std;
int a[
20005];
int s[
20005]=
intmain()
int maxx=
-0x7fffffff;
for(int i=
1;i<=n;i++
)-s[i]
+a[i];if
(sum>maxx)
maxx=sum;}}
} cout
}
4、分治解法(二分)
假設序列對應區間[l,r],其之間為mid,則最大子串行 [i,j] 有以下三種情況:
1、l<=i<=j<=mid;
2、i<=mid<=j<=r;
3、mid<=i<=j<=r;
分別取出這三種情況的值,再取他們的最大值;
複雜度:o(n)
首先,求區間[i … mid]最大值和區間[mid … j]最大值,也就是求以mid為頭的序列最大值和以mid為尾。
首先以mid為頭的序列最大值:
int maxx2=-0x7fffffff;
int sum2=0;
for( int k=mid;k<=j;k++)
以mid為尾:
int maxx1=-0x7fffffff;
int sum2=0;
for( int k=mid;k>=i;k--)
遞迴的終止條件:1、遞迴的區間為解;2、遞迴的區間只有乙個元素
#include
using
namespace std;
int a[
20005];
intfind
(int l,
int r)
//以mid為尾:
int maxx1=
-0x7fffffff;
int sum2=0;
for(
int k=mid;k>=l;k--
)return
max(
max(
find
(l,mid)
,find
(mid+
1,r)
),maxx1+maxx2-a[mid]);
intmain()
cout<<
find(1
,n)
0;
5、貪心解法
若a[i-1]序列》0,則 s[i]+a[i-1]序列》a[i];
反之,若a[i-1]<0; 則不需要加上i-1前面的序列
假設必須選擇a[i], 貪心過程的最優解就是以a[i]為結尾的子串行和s[i]最大的區域性最優解.
#include
using
namespace std;
int a[
20005];
intmain()
cout
0;
6、動態規劃
假設f[i]表示以第 i 個元素結尾的最大子串行的最大值,則:
f[i]=max(f[i-1]+a[i],a[i])
初始狀態: f[1]=a[1]
#include
using namsespace std;
int a[
20005];
int f[
20005];
intmain()
cout
0;
最大欄位和演算法
最大欄位和演算法 這個演算法在本學期的課程中,已經稍作了解。不過印象不夠深刻。今天重新複習一下,加深理解。最大欄位和,無非就是三種情況 max在左半部分 max在右半部分 max在中間 均可以使用遞迴來解決,情況三也並不是很複雜。先附上 然後逐條解釋。public class solution re...
最大欄位和
include include include include include using namespace std 最大欄位和問題描述 給定n個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的子段和的最大值。當所給的整均為負數時定義子段和為0,...
最大欄位和
1049 最大子段和 難度 基礎題 n個整數組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的連續子段和的最大值。當所給的整數均為負數時和為0。例如 2,11,4,13,5,2,和最大的子段為 11,4,13。和為20。input 第1行 整數序列的長度n 2 n 5...