赞
踩
顾名思义,贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择,不一定是全局最优的,即只有部分问题能够产生整体最优解。如单源最短路经问题,最小生成树问题等。在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很近似。
①建立数学模型来描述问题。
②把求解的问题分成若干个子问题。
③对每个子问题求解,得到子问题的局部最优解。
④把子问题的解局部最优解合成原来解问题的一个解。
贪心策略的前提是:局部最优策略能导致产生全局最优解。
实际上,贪心算法使用的情况比较少,一般对一个问题分析是否适用于贪心算法,可以先选择该问题下>的几个实际数据进行分析可以做出判断。
在贪心算法里面最常见的莫过于找零钱的问题了,题目大意如下,对于人民币的面值有1元 5元 10元 20元 50元 100元,下面要求设计一个程序,输入找零的钱,输出找钱方案中最少张数的方案,比如123元,最少是1张100的,1张20的,3张1元的,一共5张!
解析:这样的题目运用的贪心策略是每次选择最大的钱,如果最后超过了,再选择次大的面值,然后次次大的面值,一直到最后与找的钱相等,这种情况大家再熟悉不过了,下面就直接看源代码:
#include <iostream> #include <cmath> using namespace std; int main(int argc, char* argv[]) { int MoneyClass[6] = {100,50,20,10,5,1}; //记录钱的面值 int MoneyIndex [6] ={0}; //记录每种面值的数量 int MoneyAll,MoneyCount = 0,count=0; cout<<"please enter the all money you want to exchange:"<<endl; cin>>MoneyAll; for(int i=0;i<6;) //只有这个循环才是主体 { if( MoneyCount+MoneyClass[i] > MoneyAll) { i++; continue; } MoneyCount += MoneyClass[i]; ++ MoneyIndex[i]; ++ count; if(MoneyCount == MoneyAll) break; } for(i=0;i<6;++i) //控制输出的循环 { if(MoneyIndex[i] !=0 ) { switch(i) { case 0: cout<<"the 100 have:"<<MoneyIndex[i]<<endl; break; case 1: cout<<"the 50 have:"<<MoneyIndex[i]<<endl; break; case 2: cout<<"the 20 have:"<<MoneyIndex[i]<<endl; break; case 3: cout<<"the 10 have:"<<MoneyIndex[i]<<endl; break; case 4: cout<<"the 5 have:"<<MoneyIndex[i]<<endl; break; case 5: cout<<"the 1 have:"<<MoneyIndex[i]<<endl; break; } } } cout<<"the total money have:"<<count<<endl; system("pause"); return 0; }
以谈恋爱举例:
很多人来追求你。 贪心算法就是你根据你现在对他们的了解,你喜欢漂亮的,你挑一个最漂亮的,你喜欢有钱的,你挑一个最有钱的,只在意当前的最佳选择; 动态规划算法就是你对他们进行了一番深入的调查和了解之后,人品、物质、颜值等,最终选择和谁在一起!
对许多最优化问题来说,采用动态规划方法来决定最佳选择有点“杀鸡用牛刀”了,只要采用另一些更简单有效的算法就行了。贪心算法是使所做的选择看起来都是当前最佳的,期望通过所做的局部最优选择来产生出一个全局最优解。贪心算法对大多数优化问题来说能产生最优解,但也不一定总是这样的。所有如果希望贪心算法得到全局最优,需要对贪心算法进行证明。
方法:
第一数学归纳法
第一数学归纳法可以概括为以下三步:
(1)归纳奠基:证明当n=1时命题成立;
(2)归纳假设:假设当n=k时命题成立;
(3)归纳递推:由归纳假设推出当n=k+1时命题也成立.
理解:如果假设(2)成立,即:命题P(n)成立,推出命题P(n+1)成立(n为任意正整数,表明该推导数量的无穷性)。根据此假设,可以得到P(n)→P(n+1)为真,亦即有:P(1)→P(2),P(2)→P(3),P(3)→P(4),…,P(n)→P(n+1)为真,则得P(n)成立。
第二数学归纳法
第一数学归纳法可以概括为以下三步:
命题P(n)满足:
(1)当n=1时,P(1)成立
(2)假设对于正整数k,当n<k,命题P(n)成立时,命题P(n=k)也成立
(3)那么,命题P(n)对于一切正整数都成立
理解:如果假设(2)成立,即:P(1),P(2),…,P(k-1)成立(k为任意正整数,表明成立命题数量的无穷性),可以推出P(k)成立。亦即:P(1),P(2),…,P(k-1)→P(k)的推导为真(P(1),P(2),…,P(k-1)为真),此时P(n)对一切正整数成立。一般情况下P(k)不复杂时,无需把P(1),P(2),…,P(k-1)成立 这些条件全用上,部分使用即可。例如只需P(k-2),P(k-1)即可推出P(k)。
以多米诺骨牌为例的话:
第一归纳法:第一个牌会倒,且有规则:前一张牌倒,后一张牌必定会倒。牌会一直倒下去(成立下去)
第二归纳法:前一批牌会倒,且有规则:前一批牌倒,前一批牌紧接着的下一张牌必定会倒。牌会一直倒下去(成立下去)
显然第二(强归纳法)归纳法与第一归纳法相比,是把一批牌看做成一张牌,初始条件由一张牌,变成了一批牌。可能这就是它强的原因吧
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。