动态规划与贪婪算法

观点描述来源与博客:http://blog.csdn.net/woaimeinuo/article/details/45651163 

贪婪:每一次都选择当前最好的,虽然不是全局最优解,但其可以让你找到局部最优解或是次优解。其实,有次优解也不错了。贪婪算法基本上是一种急功近利的算法,但是并不代表这种算法不好,如果贪婪的是一种长远和持续,又未尝不可呢?

贪心算法:动态规划的一种特例:在区别动归和贪心的时候,关键就是:  

我们在得到当前最优解的时候,需不需要使用前面的阶段中的得到的值,如果不需要,那就是贪心;如果需要,就是动归。 

动态规划:

对于大部分的问题,贪婪法通常都不能找出最优解,因为他们一般没有测试所有可能的解。因为贪婪算法是一种短视的行为,只会跟据当前的形式做判断,也就是过早做决定,因而没法达到最佳解。

动态规划和贪婪算法的最大不同是,贪婪算法做出选择,不能在过程优化。动态规划则会保存以前的运算结果,并根据以前的结果对当前进行选择,会动态优化功能。

动态规划算法至少告诉我们两个事:

1)承前启后非常重要,当你准备去做遍历的时候,你的上次的经历不但能开启你以后的经历,而且还能为后面的经历所用。你的每一步都没有浪费。

2)是否可以回退也很重要。这意思是——如果你面前有两个选择,一个是A公司一个是B公司,如果今天你选了A公司,并不是你完全放弃了B公司。而是,你知道从A公司退出来去B公司,会比从B公司退出来去A公司要容易一些。

比如说:你有两个offer,一个是Yahoo,一个是Baidu,上述的第一点会让我们思考,我以前的特长和能力更符合Yahoo还是Baidu?而Yahoo和Baidu谁能给我开启更大的平台?上述的第二点告诉我们,是进入Yahoo后如果没有选好,是否还能再选择Baidu公司?还是进入Baidu公司后能容易回退到Yahoo公司?

 

 

动态规划就是每个子问题求的都是最优解,遍历所有的解,同时保存局部最优解和全局最优解,确保最终结果是最有解,并且每个子问题的解也是最优解。

if (nums.length == 0)
return 0;
if (nums.length == 1)
return nums[0];

int dp_max=nums[0]; //局部最优解
int dp_min=nums[0];  //全局最优依赖的数据
int max = nums[0]; //全局最优解
int preMax;
int preMin;
for (int i = 1;i< nums.length;i++) {
preMax=dp_max;
preMin=dp_min;
dp_max= (preMax*nums[i]>nums[i]?preMax*nums[i]:nums[i])>preMin*nums[i]?
(preMax*nums[i]>nums[i]?preMax*nums[i]:nums[i]):preMin*nums[i];
dp_min= (preMin*nums[i]>nums[i]?nums[i]:preMin*nums[i])>preMax*nums[i]?
preMax*nums[i]:(preMin*nums[i]>nums[i]?nums[i]:preMin*nums[i]);
max = max > dp_max ? max:dp_max;

}
return max;
posted @ 2018-03-05 11:41  mokayy  阅读(239)  评论(0编辑  收藏  举报