您的位置:首页 > 其它

动态规划解决“最大子数组”问题

2014-11-14 00:17 253 查看
TODO: 动态规划到底是个什么玩艺?

ref:http://www.cnblogs.com/waytofall/archive/2012/04/10/2439820.html

I 只考虑怎样产生更大的子组和:

假设处理到第i个节点时:

1. 考虑是否i节点是否可使子组的和变大

  a) 如果i节点大于0,则最大子组和是前面求到的数组和 加上 i节点值

b) 如果i节点小于0(等于0的话,值可以带上i,也可以不带上i,无所谓),当最大子数组的和是前面求的子组和

2. 然后考虑最大值是否应该更新了

a) 如果当前子组和大于最大和,则更新

int // 动态规划法
get_max_sub(int a[], int len)
{
int max_sum, cur_sum;
int i;

max_sum = cur_sum = a[0];

i = 0;
while (++i < len) {
if (cur_sum > 0) {
cur_sum += a[i];
} else {
cur_sum = a[i];
}

if (cur_sum > max_sum) {
max_sum = cur_sum;
}
}

return max_sum;
}

II 再细化考虑子数组的前后边界

  1. 因为子数组和是负时,则最大值就是i节点,则将左边界挪到i节点上。

2. 当i节点为负,(思维雷区!!),到于右边办什么时挪?当然是子数组和变大了再挪了(子和变大了,子数组扩张了)

int // 动态规划法
get_max_sub(int a[], int len, int <, int &rt)
{
int max_sum, cur_sum;
int i;

max_sum = cur_sum = a[0];
lt = rt = 0;

i = 0;
while (++i < len) {
if (cur_sum > 0) {
cur_sum += a[i];
} else {
cur_sum = a[i];
lt = i;
}

if (cur_sum > max_sum) {
max_sum = cur_sum;
rt = i;
}
}

return max_sum;
}

总结:

1. 思维深度一点点加深,由少及多

2. 摆脱思维惯性,避开雷区。

考虑最大子数组时,考虑的中心是历史子数组和是正还是负(即子数组和是当前第个i节点呢还是第i个节点加上以前的和呢),而不是只考虑加上i节点子数组是变大还是变小(直观/惯性思维引入雷区)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: