首先用分治法:
#include "stdio.h"
int maxsum(int a,int left,int right)
for(i=center+1;i<=right;i++)
sum=s1+s2;
if(sumvoid main()
然後是動態規劃方法:
#include "stdio.h"
int maxsum(int n,int a)
return sum;
}void main()
#include
int findgreatestsecsum(int *a,int len)
return max;
}
int main()
;
printf("%d/n", findgreatestsecsum(a,sizeof(a)/sizeof(int)));
return 0;
} #include
int findgreatestsecsum(int *a,int len)
return max;
}int main()
;printf("%d/n", findgreatestsecsum(a,sizeof(a)/sizeof(int)));
return 0;
} 的理解更加清晰了,在此向作者表示感謝。
最大子段和問題的動態規劃求解
1. 基本原理
設陣列為a[k],1≤k≤n,最大子段和x 被定義為:
jx = max
1≤i≤j ≤n k=i
不妨設:
j
b[j ] = max
1 ≤j ≤n k=m
其中m 是可變的。注意:a[j]必須是b[j]這個最大區域性受限子段和所對應子段的最右端,
好好理解此處j 和b[j]的含義是整個演算法的關鍵!
根據b[j]和x 的定義,不難發現:
x = max b[j ]
1≤j ≤n
另一方面,根據b[j]的定義,可以看出:
當b[j-1]>0 時,無論a[j]為何值,b[j]=b[j-1]+a[j];
當b[j-1]≤0 時,無論a[j]為何值,b[j]=a[j];
所以有:
b[j ] = max
1≤j ≤n
2. 具體例項
k 1 2 3 4
a[k] 3 -4 2 10
b[k] 3 -1 2 12
其中:b[1]=a[1],b[2]=b[1]+a[2],b[3]=a[3],b[4]=b[3]+a[4] ;因此,對於陣列a 而言,
最大子段和為b[4],即x=12 。
3. 程式設計實現
略,針對陣列a 進行一遍掃瞄即可。演算法實現的時間複雜度只有o(n)。
最大欄位和(dp)
設a i dp i 我們在選擇乙個元素a j 的時候,只有兩種情況,將a i 至a j 1 加上,或者從a j 以j為起點開始。我們用乙個陣列dp i 表示以i為結束的最大子段和,對於每乙個a i 加上dp i 1 成為子段,或以a i 開始成為新段的起點。因為我們只需要記錄dp值,所以複雜度是o ...
分治法 最大欄位和
問題描述 給定由n個整數 可能有負數 組成的序列,求一段連續的子串行,要求該序列和最大,並求出最大值。分析 將該序列平分為兩段 a1.an 2 an 2 an 最大欄位段和有三種情況,1 為左邊的最大子段和leftsum,2 為右邊的最大欄位和rightsum,3 由左邊靠近中點的最大連續子段 右邊...
最大欄位和小結 DP
詳情可以看這裡的講解,很詳細 poj2479 模板題,即求兩個段的最大子段和 poj2479 dp i j 表示包含第i個數的前i個數劃分為j個子段和的最大值 dp i j max j 1 k include define inf 10000000 using namespace std int d...