在《算法导论》中举了买股票和割铁棒的例子来讲明动态规划和贪心算法的主体思想。c++
贪心算法:老是作出在当前看来最好的状况。(不是总体最优的)算法
先抛出一个问题,相似于《算法导论》中的股票问题。数组
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
简单的一句话归纳,就是找一个数组中拥有最大和的子数组,返回其和。字体
答案(不惟一)只有6行,能够说是很是简洁,且便于理解了。ui
/* *@lucastan */
int maxSubArray(vector<int> &nums) {
int ans = nums[0], i, sum = 0;
for(i = 0; i < nums.size(); i++){
sum += nums[i];
ans = max(sum, ans);
sum = max(sum, 0);
}
return ans;
}复制代码
读完问题,咱们马上就能想到的是从头开始加,总能枚举出来一个。spa
这个想法能够说是很是朴实了,可是……咱们仍是继续思考吧,第二反应就是贪心算法了(若是你能想到动态规划的思想,也不错啊,能够相似的求解)。3d
首先咱们要说,贪心算法的简单定义是什么?(答案是白色字体)code
老是找到一个在当前看来最优的解。
而后,咱们如今要求的是什么?cdn
数组中拥有最大和的子数组。
这样一来,目标就明确了,咱们确定是须要遍历数组的,否则怎么能肯定咱们考虑到了数组中全部元素呢?blog
明确了目标,咱们结合贪心算法的定义,提出下一个问题,咱们怎么肯定如今的子数组元素的和到目前为止是最大的呢?
与在添加了下一个元素以前的数组进行比较。
那万一咱们加到数组的某一个位置的时候,出现了和为负的状况……
笨啊,一旦加到某个元素出现和为负的状况,咱们就应该舍弃前面的全部元素,而后在下一个元素处从新开始求和。若是等于零,那么咱们就要从这个元素开始从新求和。
另外,不要钻最大子数组在中间的这一种状况的牛角尖,除非在计算时数组前面的元素和小于等于零,不然咱们在这个代码里,永远会获得[0...x](x表明子数组的最后一个元素序号,[0...x]难道不是他的子数组吗?就算咱们最后获得数组自己,他也是该数组的子数组)。
文章看到这里,可能就有人发现了,这个问题并非真的应用了贪心算法,咱们只是借来了贪心算法一点点的思想,而后就获得了问题的解答。
(完整的贪心算法思想在这里是不能应用的,若是题目不要求子数组连续,那么却是能够完整的应用贪心算法思想,但这样一来问题也就失去了意义。)
看了标题和开头的一点点胡言乱语,你是否是真的觉得我要讲贪心算法了,哼,天真。