最大子数组问题 | DP

来源:互联网 发布:php编译安装pdo mysql 编辑:程序博客网 时间:2024/05/02 23:51

题目: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);

下面这张表说明了计算过程:

indexmax_sum1132103-15 --> 0420 517617-22 --> 08(start)18 938103111(end)43 最大值12381316143115271634

时间复杂度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;}?>


打印输出:



原创粉丝点击