http://blog.csdn.net/songjiano/article/details/6594616
给定一个数组,查找这个数组的子数组的最大和
比如{-2,5,3,-6,4,-8,6}
输出最大和8
分析:假设已经找到一个子数组的最大和,这个子数组是从数组索引i到索引j。
可以用如下式子描述,cur_max = a[i , j]; 对于下一个数,也就是索引为j+1,这个最大和是否
将a[j+1]加入cur_max,需要考虑cur_max的值和a[j+1];
如果当前的cur_max小于0,说明a[j+1] > a[i, j] + a[j]; cur_max = a[j+1];说明此时最大值从索引j+1开始
如果当前的cur_max大于或者等于0,cur_max = cur_max + a[j+1]。
每一轮需要比较cur_max和记录的max值进行比较更新。
此算法的时间复杂度为O(N) 空间复杂度为O(1);
源码:
int MaxSum( const int* numbers, unsigned int N )
{
assert( numbers );
int max = numbers[0];
int cur_max = max;
for ( int i=1; i<N; i++ )
{
if( cur_max < 0 )
cur_max = 0;
cur_max += numbers[i];
if( cur_max > max )
max = cur_max;
}
return max;
}
void main()
{
int nums[] = {-2,5,3,-6,4,-8,6};
//int nums[] = {0,-2,3,5,-1,2};
cout << MaxSum( nums, sizeof(nums) / sizeof(int) ) << endl;
system("pause");
}
http://blog.csdn.net/zhongjiekangping/article/details/6855021
《编程之美》里面对求一维,二维的都进行了讲解。
1、一维中用动态规划可以使时间复杂度降到O(n).
思想:考虑数组中A[0],与最大的一段数组(A[i],...A[j])的关系
(1)、当0=i=j时,元素A[0]本身构成最大的一段
(2)、当0=i<j时,和最大的一段以 A[0]开始
(3)、当0<i时,元素A[0]与和最大一段没有关系
假设已经知道(A[1],...A[n-1])中和最大的一段数组之和为All[1],并且已经知道(A[1],...,A[n-1])中包含A[1]的和最大一段为start[1],那么A[0]到A[n-1]中和最大的一段为max(A[0],A[0]+start[1],All[1])
动态规划总是这样,分析最后的结果,然后累加中间步骤的小结果们。
- int max(int x,int y){
- return (x > y) ? x : y;
- }
- int maxSum(int* A, int n){
- start[n-1] = A[n-1];
- All[n-1] = A[n-1];
- for(i = n-2; i>=0; i--){
- start[i] = max(A[i], A[i]+start[i+1]);
- all[i] = max(start[i],all[i+1]);
- }
- } return all[0];
- int max(int x,int y){
- return (x > y) ? x : y;
- }
- int maxSum(int* A, int n){
- start[n-1] = A[n-1];
- All[n-1] = A[n-1];
- for(i = n-2; i>=0; i--){
- start[i] = max(A[i], A[i]+start[i+1]);
- all[i] = max(start[i],all[i+1]);
- }
- } return all[0];
2、二维中,假设已经确定了矩形区域的上下边界,比如知道矩形区域的上下边界分别是第a行和第c行,现在要确定左右边界。
转化为一个一维问题,可以把每一列中第a行和第c行之间的元素看成一个整体。即求数组(BC[1],...BC[M])中和最大的一段,其中B[i] = B[a][i]+...B[c][i].
3、扩展问题;如果是三维数组呢?
我的问题是如果是高维数组呢?
----------------------------
其实不管多高维,都可以用二维数组的解法来解,三维数组就分解为两个二维平面。。对应于二维中的第a行和第c行,三维中就是第a个平面和第c平面;对应于二维中BC的数组,三维中就是BC平面。。
同样,四维就分为两个三维来做。。。
- int max(int x,int y){
- return (x > y) ? x : y;
- }
- int maxSum(int* A, int n){
- start[n-1] = A[n-1];
- All[n-1] = A[n-1];
- for(i = n-2; i>=0; i--){
- start[i] = max(A[i], A[i]+start[i+1]);
- all[i] = max(start[i],all[i+1]);
- }
- } return all[0];
- int max(int x,int y){
- return (x > y) ? x : y;
- }
- int maxSum(int* A, int n){
- start[n-1] = A[n-1];
- All[n-1] = A[n-1];
- for(i = n-2; i>=0; i--){
- start[i] = max(A[i], A[i]+start[i+1]);
- all[i] = max(start[i],all[i+1]);
- }
- } return all[0];