最大子数组问题 | DP

题目: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_sum
113
210
3-15 --> 0
420
517
61
7-22 --> 0
8(start)18 
938
1031
11(end)43 最大值
1238
1316
1431
1527
1634

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


打印输出:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值