题目:http://ac.jobdu.com/problem.php?pid=1372
参考: http://www.cnblogs.com/hello--the-world/archive/2012/08/21/2648977.html
解法:
1.穷举法:
即求x[0..n-1]中x[i...j]的之和的最大值,使用最普通的方法计算出任何x[i,j]之间各个和的最大值,然后取最大值。
经过两次循环,实际复杂度:O(n^2);
2.分治法:
将原始向量x分为两个大小近似相等的子向量a和b,然后递归地找出a,b中元素总和最大的子向量ma和mb。还有一种情况是最大子序列和在a和b之间,这个跨边界的最大子向量记为mc,通过观察可以发现:mc在a中的部分是a中包含右边界的最大子向量,同时mc在b中的部分是b中包含左边界的最大子向量。
时间复杂度:O(n*logn)
3.DP:
例如:
$arr = array(13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7);
下面这张表说明了计算过程:
index | max_sum |
1 | 13 |
2 | 10 |
3 | -15 --> 0 |
4 | 20 |
5 | 17 |
6 | 1 |
7 | -22 --> 0 |
8(start) | 18 |
9 | 38 |
10 | 31 |
11(end) | 43 最大值 |
12 | 38 |
13 | 16 |
14 | 31 |
15 | 27 |
16 | 34 |
时间复杂度O(n)
php实现:
<?php
/**
* @author:wusuopubupt
* @date:2013-10-16
* @return mixed $max:the sum of miximum subarray
* @from:CLRS 4.1 the miximum subarray problem
*
* Find the miximum subarray
*
* */
$arr = array(13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7);
function max_sub_arr($arr) {
$len = count($arr);
$max_sum = 0;
$max = 0;
$start = 0;
$end = 0;
for($i = 0; $i < $len; $i++) {
$max_sum = max($arr[$i]+$max_sum,0);
if(0 == $max_sum) {
$start = $i+1; //start
}
$max = max($max,$max_sum);
if($max_sum == $max) {
$end = $i; //end
}
echo"i:$i arr[$i]:$arr[$i] max_sum:$max_sum max:$max";echo"<br>";
}
for($j = $start; $j <= $end; $j++) {
var_dump($arr[$j]);
}
return $max;
}
?>
打印输出: