DP 分治 最大字段

2021-05-21 22:56:48 字數 1626 閱讀 7098

首先用分治法:

#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...